Skip to content

Commit

Permalink
#1645: show password prompt dialog when the server requires authentic…
Browse files Browse the repository at this point in the history
…ation and we don't have a password available

git-svn-id: https://xpra.org/svn/Xpra/trunk@16907 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Sep 18, 2017
1 parent 343ff69 commit 5ea02fa
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 6 deletions.
9 changes: 4 additions & 5 deletions src/xpra/client/client_base.py
Expand Up @@ -340,7 +340,6 @@ def send_hello(self, challenge_response=None, client_salt=None):
self.quit(EXIT_INTERNAL_ERROR)
return
if challenge_response:
assert self.has_password(), "got a password challenge response but we don't have a password! (malicious or broken server?)"
hello["challenge_response"] = challenge_response
if client_salt:
hello["challenge_client_salt"] = client_salt
Expand Down Expand Up @@ -551,14 +550,14 @@ def _process_connection_lost(self, _packet):

def _process_challenge(self, packet):
authlog("processing challenge: %s", packet[1:])
password = self.load_password()
self.send_challenge_reply(packet, password)

def send_challenge_reply(self, packet, password):
def warn_server_and_exit(code, message, server_message="authentication failed"):
authlog.error("Error: authentication failed:")
authlog.error(" %s", message)
self.disconnect_and_quit(code, server_message)
if not self.has_password():
warn_server_and_exit(EXIT_PASSWORD_REQUIRED, "this server requires authentication, please provide a password", "no password available")
return
password = self.load_password()
if not password:
warn_server_and_exit(EXIT_PASSWORD_FILE_ERROR, "failed to load password from file %s" % self.password_file, "no password available")
return
Expand Down
54 changes: 53 additions & 1 deletion src/xpra/client/gtk_base/gtk_client_base.py
Expand Up @@ -7,7 +7,7 @@

import os
import weakref
from xpra.gtk_common.gobject_compat import import_gobject, import_gtk, import_gdk, is_gtk3
from xpra.gtk_common.gobject_compat import import_gobject, import_gtk, import_gdk, import_pango, is_gtk3
from xpra.client.gtk_base.gtk_client_window_base import HAS_X11_BINDINGS, XSHAPE
gobject = import_gobject()
gtk = import_gtk()
Expand All @@ -30,6 +30,7 @@
from xpra.os_util import bytestostr, WIN32, OSX, POSIX
from xpra.simple_stats import std_unit
from xpra.net.compression import Compressible
from xpra.exit_codes import EXIT_PASSWORD_REQUIRED
from xpra.gtk_common.cursor_names import cursor_types
from xpra.gtk_common.gtk_util import get_gtk_version_info, scaled_image, get_default_cursor, \
new_Cursor_for_display, new_Cursor_from_pixbuf, icon_theme_get_default, \
Expand All @@ -47,6 +48,7 @@

METADATA_SUPPORTED = os.environ.get("XPRA_METADATA_SUPPORTED")
USE_LOCAL_CURSORS = envbool("XPRA_USE_LOCAL_CURSORS", True)
PASSWORD_PROMPT = envbool("XPRA_PASSWORD_PROMPT", True)


class GTKXpraClient(UIXpraClient, GObjectXpraClient):
Expand Down Expand Up @@ -156,6 +158,56 @@ def cleanup(self):
UIXpraClient.cleanup(self)


def _process_challenge(self, packet):
password = self.load_password()
if password:
self.send_challenge_reply(packet, password)
return
if not PASSWORD_PROMPT:
self.quit(EXIT_PASSWORD_REQUIRED)
return
dialog = gtk.Dialog("Server Authentication",
None,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
def add(widget, padding=0):
a = gtk.Alignment(0.5, 0.5, 1, 1)
a.add(widget)
a.set_padding(padding, padding, padding, padding)
dialog.vbox.pack_start(a)
def handle_response(dialog, response):
password = password_input.get_text()
dialog.hide()
dialog.destroy()
if response!=gtk.RESPONSE_ACCEPT or not password:
self.quit(EXIT_PASSWORD_REQUIRED)
return
self.send_challenge_reply(packet, password)
pango = import_pango()
title = gtk.Label("Server Authentication")
title.modify_font(pango.FontDescription("sans 14"))
add(title, 16)
text = "Please enter the password"
try:
from xpra.net.bytestreams import pretty_socket
conn = self._protocol._conn
text += " for %s server %s" % (conn.socktype, pretty_socket(conn.remote))
except:
pass
add(gtk.Label(text), 10)
def password_activate(*_args):
handle_response(dialog, gtk.RESPONSE_ACCEPT)
password_input = gtk.Entry(max=255)
password_input.set_width_chars(32)
password_input.set_visibility(gtk.FALSE)
password_input.connect("activate", password_activate)
add(password_input, 10)
dialog.vbox.show_all()
dialog.connect("response", handle_response)
dialog.show()


def show_start_new_command(self, *args):
log("show_start_new_command%s current start_new_command=%s, flag=%s", args, self.start_new_command, self.start_new_commands)
if self.start_new_command is None:
Expand Down

0 comments on commit 5ea02fa

Please sign in to comment.