Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* fix description of auth and vsock command line help
* add auth info to xpra info
* use auth=module[:NAME=VALUE] for supplying the password file for each module
* verify we have non-tcp sockets we can use for printing, disable it if not
* man page updates: remove "--password-file" for server, as it should no longer be used
* default config file cleanups
* refactored parse_simple_dict to util (also used in sound)

git-svn-id: https://xpra.org/svn/Xpra/trunk@12332 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Apr 8, 2016
1 parent 37b441f commit fb351da
Show file tree
Hide file tree
Showing 16 changed files with 275 additions and 203 deletions.
88 changes: 55 additions & 33 deletions src/etc/xpra/xpra.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ remote-logging = %(remote_logging)s


################################################################################
# File transfer
# File transfers

# Receive files
file-transfer = yes
Expand All @@ -77,6 +77,16 @@ file-transfer = yes
# File size limit in MB
file-size-limit = 10

# How to open files:
#open-command = xdg-open

# Open files
open-files = no


################################################################################
# Printer forwarding

# Print support:
printing = %(printing)s

Expand All @@ -97,12 +107,6 @@ postscript-printer = %(postscript_printer)s
# pdf-printer = /usr/share/ppd/cupsfilters/Generic-PDF_Printer-PDF.ppd
pdf-printer = %(pdf_printer)s

# How to open files:
#open-command = xdg-open

# Open files
open-files = no


################################################################################
# Picture Encoding
Expand Down Expand Up @@ -176,6 +180,18 @@ auto-refresh-delay = 0.15
#automatic (which is the default):
#dpi = 0

# Video encoders loaded by the server
# (all of them unless specified)
# examples:
#video-encoders=x264,vpx,nvenc
#video-encoders=x264

# Colourspace conversion modules loaded by the server
# (all of them unless specified)
# examples:
#csc-modules=swscale,cython,opencl
#csc-modules=swscale


################################################################################
# Sound Encoding
Expand Down Expand Up @@ -373,14 +389,26 @@ exit-with-children = no
# dbus-launch = /usr/bin/dbus-launch --close-stderr
dbus-launch = dbus-launch --close-stderr

# A wrapper for executing commands
# Start a dbus server which can be used to interact with the server process:
#dbus-control = no
dbus-control = %(dbus_control)s

# Forward client dbus rpc requests:
# (requires client configuration)
#dbus-proxy = no
dbus-proxy = %(dbus_proxy)s

# A wrapper for executing all sub-commands:
# exec-wrapper = vglrun --
# exec-wrapper = vglrun -d :1 --

# Allows clients to start new commands in the server context:
#start-new-commands = yes
start-new-commands = no

########################################################################
# Server Connection Options:

# Where to create local sockets:
# bind=none
# bind=auto
Expand All @@ -390,7 +418,7 @@ start-new-commands = no
# bind=/run/user/$UID/xpra/
bind = %(bind)s

# Authentication module to use:
# Authentication module to use for local sockets:
#auth=fail
#auth=reject
#auth=allow
Expand All @@ -399,26 +427,20 @@ bind = %(bind)s
#auth=sys
#auth=none

# To listen on TCP sockets:
# bind-tcp=:10000
# bind-tcp=0.0.0.0:10000
# bind-tcp=192.168.0.1:10000

# Authentication module to use for TCP sockets:
#tcp-auth=none

# Set the _NET_WM_NAME,
# used by some application that make too many assumptions (ie: Java)
# To workaround JDK6 window positioning issues, use:
#wm-name = Sawfish
wm-name = Xpra

# Video encoders loaded by the server
# (all of them unless specified)
# examples:
#video-encoders=x264,vpx,nvenc
#video-encoders=x264
# To listen on AF_VSOCK sockets:
# bind-vsock=auto:2000
# bind-vsock=2:2000

# Colourspace conversion modules loaded by the server
# (all of them unless specified)
# examples:
#csc-modules=swscale,cython,opencl
#csc-modules=swscale
# Authentication to use for VSOCK:
#vsock-auth=none

# Where to send non xpra clients:
# (can be used to share the port with a web server)
Expand All @@ -434,14 +456,14 @@ wm-name = Xpra
#mdns = no
mdns = %(mdns)s

# Forward client dbus rpc requests:
# (requires client configuration)
#dbus-proxy = no
dbus-proxy = %(dbus_proxy)s
########################################################################
# Server Environment:

# Start a dbus server which can be used to interact with the server process:
#dbus-control = no
dbus-control = %(dbus_control)s
# Set the _NET_WM_NAME,
# used by some application that make too many assumptions (ie: Java)
# To workaround JDK6 window positioning issues, use:
#wm-name = Sawfish
wm-name = Xpra

# Input methods
# To disable input method completely:
Expand Down Expand Up @@ -479,7 +501,7 @@ pulseaudio-command = %(pulseaudio_command)s
sync-xvfb = 0

# Virtual display command:
# - Old Xvfb option:
# - Old Xvfb option (required on Ubuntu where Xorg is broken):
# xvfb = Xvfb +extension Composite -nolisten tcp -noreset \
# -auth $XAUTHORITY \
# -screen 0 5760x2560x24+32
Expand Down
7 changes: 4 additions & 3 deletions src/xpra/scripts/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ def ignore(defaults):
group.add_option("--bind-tcp", action="append",
dest="bind_tcp", default=list(defaults.bind_tcp or []),
metavar="[HOST]:PORT",
help="Listen for connections over TCP (use --password-file to secure it)."
help="Listen for connections over TCP (use --tcp-auth to secure it)."
+ " You may specify this option multiple times with different host and port combinations")
else:
ignore({"bind-tcp" : []})
Expand All @@ -389,7 +389,7 @@ def ignore(defaults):
group.add_option("--bind-vsock", action="append",
dest="bind_vsock", default=list(defaults.bind_vsock or []),
metavar="[CID]:[PORT]",
help="Listen for connections over VSOCK (use --password-file to secure it)."
help="Listen for connections over VSOCK."
+ " You may specify this option multiple times with different CID and port combinations")
else:
ignore({"bind-vsock" : []})
Expand Down Expand Up @@ -1150,7 +1150,8 @@ def parse_display_name(error_cb, opts, display_name):
with open(opts.password_file, "rb") as f:
desc["password"] = f.read()
except Exception as e:
print("failed to read password file %s: %s", opts.password_file, e)
sys.stderr.write("Error: failed to read the password file '%s':\n", opts.password_file)
sys.stderr.write(" %s\n", e)
return desc
elif display_name.startswith("socket:"):
#use the socketfile specified:
Expand Down
2 changes: 0 additions & 2 deletions src/xpra/scripts/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,8 +916,6 @@ def run_server(error_cb, opts, mode, xpra_file, extra_args, desktop_display=None
except:
cwd = os.path.expanduser("~")
sys.stderr.write("current working directory does not exist, using '%s'\n" % cwd)
if opts.password_file and not (opts.auth or opts.tcp_auth):
raise InitException("when specifying a password-file, you must use auth or tcp-auth")
validate_encryption(opts)
if opts.encoding=="help" or "help" in opts.encodings:
#avoid errors and warnings:
Expand Down
2 changes: 1 addition & 1 deletion src/xpra/server/auth/fail_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def init(opts):
pass

class Authenticator(object):
def __init__(self, username=""):
def __init__(self, username="", **kwargs):
raise Exception("failing")

def __repr__(self):
Expand Down
70 changes: 6 additions & 64 deletions src/xpra/server/auth/file_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,78 +6,20 @@
#authentication from a file containing just the password

import binascii
import os.path
import hmac, hashlib

from xpra.os_util import get_hex_uuid, strtobytes
from xpra.server.auth.sys_auth_base import SysAuthenticator
from xpra.os_util import strtobytes
from xpra.server.auth.file_auth_base import FileAuthenticatorBase, init
from xpra.util import xor
from xpra.log import Logger
log = Logger("auth")


password_file = None
password_data = None
password_file_time = None
def init(opts):
global password_data, password_file_time, password_file
password_file = opts.password_file
password_data = None
password_file_time = None
#will be called when we init the module
assert init


def get_password_file_time():
try:
return os.stat(password_file).st_mtime
except Exception as e:
log.error("error accessing password file time: %s", e)
return 0
def load_password_file():
global password_data, password_file_time, password_file
if not password_file:
return None
if not os.path.exists(password_file):
log.error("Error: password file %s is missing", password_file)
password_data = None
return password_data
ptime = get_password_file_time()
if password_data is None or ptime!=password_file_time:
password_file_time = None
password_data = None
try:
with open(password_file, mode='rb') as f:
password_data = f.read()
log("loaded %s bytes from %s", len(password_data), password_file)
password_file_time = ptime
except Exception as e:
log.error("error loading %s: %s", password_file, e)
password_data = None
return password_data


class Authenticator(SysAuthenticator):
def __init__(self, username):
SysAuthenticator.__init__(self, username)
self.salt = None

def requires_challenge(self):
return True

def get_challenge(self):
if self.salt is not None:
log.error("challenge already sent!")
if self.salt is not False:
self.salt = False
return None
self.salt = get_hex_uuid()+get_hex_uuid()
#this authenticator can use the safer "hmac" digest:
return self.salt, "hmac"

def get_password(self):
file_data = load_password_file()
if file_data is None:
return None
return strtobytes(file_data)
class Authenticator(FileAuthenticatorBase):

def authenticate(self, challenge_response, client_salt):
if not self.salt:
Expand All @@ -92,7 +34,7 @@ def authenticate(self, challenge_response, client_salt):
password = self.get_password()
if not password:
log.error("Error: authentication failed")
log.error(" no password for '%s' in %s", self.username, password_file)
log.error(" no password for '%s' in '%s'", self.username, self.password_filename)
return False
verify = hmac.HMAC(strtobytes(password), strtobytes(salt), digestmod=hashlib.md5).hexdigest()
log("authenticate(%s) password=%s, hex(salt)=%s, hash=%s", challenge_response, password, binascii.hexlify(strtobytes(salt)), verify)
Expand Down
82 changes: 82 additions & 0 deletions src/xpra/server/auth/file_auth_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# This file is part of Xpra.
# Copyright (C) 2013-2016 Antoine Martin <[email protected]>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

#authentication from a file containing just the password

import os.path

from xpra.os_util import get_hex_uuid, strtobytes
from xpra.server.auth.sys_auth_base import SysAuthenticator
from xpra.log import Logger
log = Logger("auth")


#legacy interface: this is to inject the "--password-file=" option
#this is shared by all instances
password_file = None
def init(opts):
global password_file
password_file = opts.password_file


class FileAuthenticatorBase(SysAuthenticator):
def __init__(self, username, **kwargs):
SysAuthenticator.__init__(self, username)
self.password_filename = kwargs.get("filename", password_file)
self.password_filedata = None
self.password_filetime = None

def requires_challenge(self):
return True

def get_challenge(self):
if self.salt is not None:
log.error("challenge already sent!")
if self.salt is not False:
self.salt = False
return None
self.salt = get_hex_uuid()+get_hex_uuid()
#this authenticator can use the safer "hmac" digest:
return self.salt, "hmac"

def get_password(self):
file_data = self.load_password_file()
if file_data is None:
return None
return strtobytes(file_data)

def parse_filedata(self, data):
return data

def load_password_file(self):
if not self.password_filename:
return None
if not os.path.exists(self.password_filename):
log.error("Error: password file %s is missing", self.password_filename)
self.password_filedata = None
else:
ptime = self.stat_password_filetime()
if self.password_filedata is None or ptime!=self.password_filetime:
self.password_filetime = None
self.password_filedata = None
try:
with open(self.password_filename, mode='rb') as f:
data = f.read()
log("loaded %s bytes from %s", len(data), self.password_filename)
self.password_filedata = self.parse_filedata(data)
self.password_filetime = ptime
except Exception as e:
log.error("Error password from '%s':", password_file)
log.error(" %s", e)
self.password_filedata = None
return self.password_filedata

def stat_password_filetime(self):
try:
return os.stat(self.password_filename).st_mtime
except Exception as e:
log.error("Error accessing time of password file '%s'", self.password_filename)
log.error(" %s", e)
return 0
Loading

0 comments on commit fb351da

Please sign in to comment.