Skip to content

Commit

Permalink
#1728: make it possible to tell the client what we are prompting for,…
Browse files Browse the repository at this point in the history
… defaults to "password"

git-svn-id: https://xpra.org/svn/Xpra/trunk@17776 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Dec 29, 2017
1 parent 4ace1d7 commit 37a9f96
Show file tree
Hide file tree
Showing 11 changed files with 36 additions and 28 deletions.
15 changes: 9 additions & 6 deletions src/xpra/client/client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from xpra.version_util import version_compat_check, get_version_info, XPRA_VERSION
from xpra.platform.info import get_name
from xpra.os_util import get_machine_id, get_user_uuid, load_binary_file, SIGNAMES, PYTHON3, strtobytes, bytestostr, hexstr
from xpra.util import flatten_dict, typedict, updict, xor, repr_ellipsized, nonl, envbool, envint, disconnect_is_an_error, dump_all_frames
from xpra.util import flatten_dict, typedict, updict, xor, repr_ellipsized, nonl, std, envbool, envint, disconnect_is_an_error, dump_all_frames
from xpra.net.file_transfer import FileTransferHandler

from xpra.exit_codes import (EXIT_OK, EXIT_CONNECTION_LOST, EXIT_TIMEOUT, EXIT_UNSUPPORTED,
Expand Down Expand Up @@ -577,7 +577,10 @@ def _process_challenge(self, packet):
authlog("processing challenge: %s", packet[1:])
if not self.validate_challenge_packet(packet):
return
password = self.load_password()
prompt = "password"
if len(packet)>=6:
prompt = std(packet[5])
password = self.load_password(prompt)
if not password:
self.quit(EXIT_PASSWORD_REQUIRED)
else:
Expand Down Expand Up @@ -610,8 +613,8 @@ def validate_challenge_packet(self, packet):
log.warn("Warning: server using legacy support for '%s' salt digest", salt_digest)
return True

def get_challenge_prompt(self):
text = "Please enter the password"
def get_challenge_prompt(self, prompt="password"):
text = "Please enter the %s" % (prompt,)
try:
from xpra.net.bytestreams import pretty_socket
conn = self._protocol._conn
Expand Down Expand Up @@ -697,7 +700,7 @@ def get_encryption_key(self):
raise InitExit(1, "no encryption key")
return key.strip("\n\r")

def load_password(self):
def load_password(self, prompt="password"):
authlog("load_password() existing value found: %s", bool(self.password))
if self.password:
return self.password
Expand All @@ -712,7 +715,7 @@ def load_password(self):
if sys.stdin.isatty() and not os.environ.get("MSYSCON"):
import getpass
authlog("stdin isatty, using password prompt")
password = getpass.getpass("%s :" % self.get_challenge_prompt())
password = getpass.getpass("%s :" % self.get_challenge_prompt(prompt))
except Exception:
authlog("password request failure", exc_info=True)
return password
Expand Down
2 changes: 1 addition & 1 deletion src/xpra/client/gtk_base/client_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ def do_start_XpraClient(self, conn, display_desc={}):

if self.config.password:
#pass the password to the class directly:
def load_password():
def load_password(*_args):
return self.config.password
self.client.password_file = "FAKE-PASSWORD-FILE-FOR-LAUNCHER"
self.client.load_password = load_password
Expand Down
9 changes: 6 additions & 3 deletions src/xpra/client/gtk_base/gtk_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

from xpra.gtk_common.quit import (gtk_main_quit_really,
gtk_main_quit_on_fatal_exceptions_enable)
from xpra.util import updict, pver, iround, flatten_dict, envbool, typedict, repr_ellipsized, DEFAULT_METADATA_SUPPORTED
from xpra.util import updict, pver, iround, flatten_dict, envbool, typedict, repr_ellipsized, std, DEFAULT_METADATA_SUPPORTED
from xpra.os_util import bytestostr, strtobytes, hexstr, WIN32, OSX, POSIX, PYTHON3
from xpra.simple_stats import std_unit
from xpra.net.compression import Compressible
Expand Down Expand Up @@ -173,7 +173,10 @@ def cleanup(self):
def _process_challenge(self, packet):
if not self.validate_challenge_packet(packet):
return
password = self.load_password()
prompt = "password"
if len(packet)>=6:
prompt = std(packet[5])
password = self.load_password(prompt)
if password:
self.send_challenge_reply(packet, password)
return
Expand Down Expand Up @@ -205,7 +208,7 @@ def handle_response(dialog, response):
title = gtk.Label("Server Authentication")
title.modify_font(pango.FontDescription("sans 14"))
add(title, 16)
add(gtk.Label(self.get_challenge_prompt()), 10)
add(gtk.Label(self.get_challenge_prompt(prompt)), 10)
def password_activate(*_args):
handle_response(dialog, gtk.RESPONSE_ACCEPT)
password_input = gtk.Entry(max=255)
Expand Down
4 changes: 2 additions & 2 deletions src/xpra/server/auth/env_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
class Authenticator(SysAuthenticator):

def __init__(self, username, **kwargs):
SysAuthenticator.__init__(self, username)
self.var_name = kwargs.get("name", "XPRA_PASSWORD")
self.var_name = kwargs.pop("name", "XPRA_PASSWORD")
SysAuthenticator.__init__(self, username, **kwargs)
self.authenticate = self.authenticate_hmac

def __repr__(self):
Expand Down
4 changes: 2 additions & 2 deletions src/xpra/server/auth/file_auth_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def init(opts):

class FileAuthenticatorBase(SysAuthenticator):
def __init__(self, username, **kwargs):
SysAuthenticator.__init__(self, username)
filename = kwargs.get("filename", password_file)
filename = kwargs.pop("filename", password_file)
if filename and not os.path.isabs(filename):
exec_cwd = kwargs.get("exec_cwd", os.getcwd())
filename = os.path.join(exec_cwd, filename)
SysAuthenticator.__init__(self, username, **kwargs)
self.password_filename = filename
self.password_filedata = None
self.password_filetime = None
Expand Down
4 changes: 2 additions & 2 deletions src/xpra/server/auth/password_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
class Authenticator(SysAuthenticator):

def __init__(self, username, **kwargs):
SysAuthenticator.__init__(self, username)
self.value = kwargs.get("value")
self.value = kwargs.pop("value")
SysAuthenticator.__init__(self, username, **kwargs)
self.authenticate = self.authenticate_hmac

def __repr__(self):
Expand Down
6 changes: 3 additions & 3 deletions src/xpra/server/auth/peercred_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@
class Authenticator(SysAuthenticator):

def __init__(self, username, **kwargs):
SysAuthenticator.__init__(self, username)
log("peercred.Authenticator(%s, %s)", username, kwargs)
self.uid = -1
self.gid = -1
if not POSIX:
log.warn("Warning: peercred authentication is not supported on %s", os.name)
return
connection = kwargs.get("connection", None)
uids = kwargs.get("uid")
gids = kwargs.get("gid")
uids = kwargs.pop("uid", None)
gids = kwargs.pop("gid", None)
allow_uids = None
allow_gids = None
if uids:
Expand Down Expand Up @@ -77,6 +76,7 @@ def __init__(self, username, **kwargs):
except Exception as e:
log.error("Error: cannot get peer uid")
log.error(" %s", e)
SysAuthenticator.__init__(self, username, **kwargs)

def get_uid(self):
return self.uid
Expand Down
3 changes: 2 additions & 1 deletion src/xpra/server/auth/reject_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ def init(opts):


class Authenticator(object):
def __init__(self, username, **_kwargs):
def __init__(self, username, **kwargs):
self.username = username
self.challenge_sent = False
self.prompt = kwargs.pop("prompt", "password")
self.passed = False

def requires_challenge(self):
Expand Down
8 changes: 4 additions & 4 deletions src/xpra/server/auth/sqlite_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ def init(opts):
class Authenticator(SysAuthenticator):

def __init__(self, username, **kwargs):
SysAuthenticator.__init__(self, username)
filename = kwargs.get("filename", 'sqlite.sdb')
filename = kwargs.pop("filename", 'sqlite.sdb')
if filename and not os.path.isabs(filename):
exec_cwd = kwargs.get("exec_cwd", os.getcwd())
filename = os.path.join(exec_cwd, filename)
self.filename = filename
self.password_query = kwargs.get("password_query", "SELECT password FROM users WHERE username=(?)")
self.sessions_query = kwargs.get("sessions_query", "SELECT uid, gid, displays, env_options, session_options FROM users WHERE username=(?)")
self.password_query = kwargs.pop("password_query", "SELECT password FROM users WHERE username=(?)")
self.sessions_query = kwargs.pop("sessions_query", "SELECT uid, gid, displays, env_options, session_options FROM users WHERE username=(?)")
SysAuthenticator.__init__(self, username, **kwargs)
self.authenticate = self.authenticate_hmac

def __repr__(self):
Expand Down
1 change: 1 addition & 0 deletions src/xpra/server/auth/sys_auth_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def __init__(self, username, **kwargs):
self.salt = None
self.digest = None
self.salt_digest = None
self.prompt = kwargs.pop("prompt", "password")
self.challenge_sent = False
self.passed = False
try:
Expand Down
8 changes: 4 additions & 4 deletions src/xpra/server/server_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1283,8 +1283,8 @@ def make_authenticators(self, socktype, username, conn):
i += 1
return tuple(authenticators)

def send_challenge(self, proto, salt, digest, salt_digest, auth_caps=None):
proto.send_now(("challenge", salt, auth_caps or "", digest, salt_digest))
def send_challenge(self, proto, salt, auth_caps, digest, salt_digest, prompt="password"):
proto.send_now(("challenge", salt, auth_caps or "", digest, salt_digest, prompt))
self.schedule_verify_connection_accepted(proto, CHALLENGE_TIMEOUT)

def verify_auth(self, proto, packet, c):
Expand Down Expand Up @@ -1344,7 +1344,7 @@ def send_fake_challenge():
salt = get_salt()
digest = choose_digest(digest_modes)
salt_digest = choose_digest(salt_digest_modes)
self.send_challenge(proto, salt, digest, salt_digest, auth_caps)
self.send_challenge(proto, salt, auth_caps, digest, salt_digest)

#skip the authentication module we have "passed" already:
remaining_authenticators = tuple(x for x in proto.authenticators if not x.passed)
Expand Down Expand Up @@ -1398,7 +1398,7 @@ def send_fake_challenge():
auth_failed("insecure salt digest '%s' rejected" % salt_digest)
return
log.warn("Warning: using legacy support for '%s' salt digest", salt_digest)
self.send_challenge(proto, salt, digest, salt_digest, auth_caps)
self.send_challenge(proto, salt, auth_caps, digest, salt_digest, authenticator.prompt)
return
#challenge has been sent already for this module
if not challenge_response:
Expand Down

0 comments on commit 37a9f96

Please sign in to comment.