def do_check_peercred(self, connection, allow_uids=None, allow_gids=None): try: from xpra.net.bytestreams import SocketConnection if connection and isinstance(connection, SocketConnection): sock = connection._socket peercred = get_peercred(sock) log("get_peercred(%s)=%s", sock, peercred) if not peercred: log.warn("Warning: failed to get peer credentials on %s", sock) return _, uid, gid = peercred if allow_uids is not None and uid not in allow_uids: log.warn("Warning: peercred access denied,") log.warn(" uid %i is not in the whitelist: %s", uid, csv(allow_uids)) elif allow_gids is not None and gid not in allow_gids: log.warn("Warning: peercred access denied,") log.warn(" gid %i is not in the whitelist: %s", gid, csv(allow_gids)) else: self.peercred_check = True self.uid = uid self.gid = gid else: log( "peercred: invalid connection '%s' (not a socket connection)", connection) except Exception as e: log("peercred", exc_info=True) log.error("Error: cannot get peer uid") log.error(" %s", e)
def check(self, token) -> bool: log("check(%r)", token) assert self.challenge_sent try: if WIN32: import winkerberos as kerberos #@UnresolvedImport @UnusedImport else: import kerberos #@UnresolvedImport @Reimport except ImportError as e: log("check(..)", exc_info=True) log.warn("Warning: cannot use kerberos token authentication:") log.warn(" %s", e) return False v, ctx = kerberos.authGSSServerInit(self.service) if v != 1: log.error( "Error: kerberos GSS server init failed for service '%s'", self.service) return False try: r = kerberos.authGSSServerStep(ctx, token) log("kerberos auth server step result: %s", r == 1) if r != 1: return False targetname = kerberos.authGSSServerTargetName(ctx) #response = kerberos.authGSSServerResponse(ctx) principal = kerberos.authGSSServerUserName(ctx) #ie: user1@LOCALDOMAIN #maybe we should validate the realm? log("kerberos targetname=%s, principal=%s", targetname, principal) return True finally: kerberos.authGSSServerClean(ctx)
def authenticate(self, _challenge_response=None, _client_salt=None): if not self.host or not check_host(self.peername, self.host): errinfo = "'%s'" % self.peername if self.peername != self.host: errinfo += " ('%s')" % self.host log.warn("Warning: access denied for host %s" % errinfo) return False return True
def authenticate(self, caps: typedict) -> bool: if not self.host or not check_host(self.peername, self.host): errinfo = "'%s'" % self.peername if self.peername != self.host: errinfo += " ('%s')" % self.host log.warn("Warning: access denied for host %s" % errinfo) return False return True
def check(self, password): log("check(%s)", obsc(password)) try: from ldap3 import Server, Connection, Tls, ALL, SIMPLE, SASL, NTLM #@UnresolvedImport except ImportError as e: log("check(..)", exc_info=True) log.warn("Warning: cannot use ldap3 authentication:") log.warn(" %s", e) return False try: MECHANISM = { "SIMPLE": SIMPLE, "SASL": SASL, "NTLM": NTLM, } authentication = MECHANISM[self.authentication] tls = None if self.tls: tls = Tls(validate=self.tls_validate, version=self.tls_version, ca_certs_file=self.cacert) log("TLS=%s", tls) server = Server(self.host, port=self.port, tls=tls, use_ssl=self.tls, get_info=ALL) log("ldap3 Server(%s)=%s", (self.host, self.port, self.tls), server) conn = Connection(server, user=self.username, password=password, authentication=authentication, receive_timeout=10) log("ldap3 Connection(%s, %s, %s)=%s", server, self.username, self.authentication, conn) if self.tls: conn.start_tls() r = conn.bind() log("ldap3 %s.bind()=%s", conn, r) if not r: return False if is_debug_enabled("auth"): log("ldap3 server info:") for l in server.info.splitlines(): log(" %s", l) log("ldap3 who_am_i()=%s", conn.extend.standard.who_am_i()) return True except Exception as e: log("ldap3 check(..)", exc_info=True) log.error("Error: ldap3 authentication failed:") log.error(" %s", e) return False
def check(self, password): log("check(%s)", obsc(password)) def emsg(e): try: log.warn(" LDAP Error: %s", e.message["desc"]) if "info" in e.message: log.warn(" %s", e.message["info"]) except: #python3: no way to get to the message dict? log.warn(" %s", e) try: import ldap except ImportError as e: log("check(..)", exc_info=True) log.warn("Warning: cannot use ldap authentication:") log.warn(" %s", e) return False try: assert self.username and password if self.tls: protocol = "ldaps" else: protocol = "ldap" server = "%s://%s:%i" % (protocol, self.host, self.port) conn = ldap.initialize(server, trace_level=LDAP_TRACE_LEVEL or is_debug_enabled("auth")) conn.protocol_version = LDAP_PROTOCOL_VERSION conn.set_option(ldap.OPT_REFERRALS, LDAP_REFERRALS) if self.cacert: conn.set_option(ldap.OPT_X_TLS_CACERTFILE, self.cacert) log("ldap.open(%s)=%s", server, conn) try: domain = socket.getfqdn().split(".", 1)[1] except: domain = "localdomain" user = self.username_format.replace("%username", self.username).replace("%domain", domain) log("user=%s", user) try: #password should be the result of a digest function, #ie: xor will return bytes.. p = bytestostr(password) password = p.encode(self.encoding) log("ldap encoded password as %s", self.encoding) except: pass v = conn.simple_bind_s(user, password) log("simple_bind_s(%s, %s)=%s", user, obsc(password), v) return True except ldap.INVALID_CREDENTIALS: log("check(..)", exc_info=True) return False except ldap.SERVER_DOWN as e: log("check(..)", exc_info=True) log.warn("Warning: LDAP %sserver at %s:%i is unreachable", ["", "TLS "][self.tls], self.host, self.port) emsg(e) except ldap.LDAPError as e: log("check(..)", exc_info=True) log.warn("Error: ldap authentication failed:") emsg(e) return False
def check(self, token): log("check(%s)", repr(token)) assert self.challenge_sent try: from gssapi import creds as gsscreds from gssapi import sec_contexts as gssctx except ImportError as e: log("check(..)", exc_info=True) log.warn("Warning: cannot use gss authentication:") log.warn(" %s", e) return False server_creds = gsscreds.Credentials(usage='accept') server_ctx = gssctx.SecurityContext(creds=server_creds) server_ctx.step(token) return server_ctx.complete
def __init__(self, **kwargs): log("peercred.Authenticator(%s)", kwargs) self.uid = -1 self.gid = -1 self.peercred_check = False if not POSIX: log.warn("Warning: peercred authentication is not supported on %s", os.name) return connection = kwargs.get("connection", None) uids = kwargs.pop("uid", "") gids = kwargs.pop("gid", "") allow_owner = kwargs.pop("allow-owner", "yes").lower() in TRUE_OPTIONS self.check_peercred(connection, uids, gids, allow_owner) super().__init__(**kwargs)
def __init__(self, **kwargs): self.app_id = kwargs.pop("app_id", APP_ID) key_hexstring = kwargs.pop("public_key", "") super().__init__(**kwargs) self.public_keys = {} key_strs = {} if key_hexstring: log("u2f_auth: public key from configuration=%s", key_hexstring) key_strs["command-option"] = key_hexstring #try to load public keys from the user conf dir(s): if getuid() == 0 and POSIX: #root: use the uid of the username specified: uid = self.get_uid() else: uid = getuid() conf_dirs = get_user_conf_dirs(uid) log("u2f: will try to load public keys from %s", csv(conf_dirs)) #load public keys: for d in conf_dirs: ed = osexpand(d) if os.path.exists(ed) and os.path.isdir(ed): pub_keyfiles = glob.glob(os.path.join(ed, "u2f*-pub.hex")) log("u2f: keyfiles(%s)=%s", ed, pub_keyfiles) for f in sorted(pub_keyfiles): key_hexstring = load_binary_file(f) if key_hexstring: key_hexstring = key_hexstring.rstrip(b" \n\r") key_strs[f] = key_hexstring log("u2f_auth: loaded public key from file '%s': %s", f, key_hexstring) #parse public key data: #pylint: disable=import-outside-toplevel from cryptography.hazmat.primitives.serialization import load_der_public_key from cryptography.hazmat.backends import default_backend for origin, key_hexstring in key_strs.items(): try: key = binascii.unhexlify(key_hexstring) except Exception as e: log("unhexlify(%s)", key_hexstring, exc_info=True) log.warn("Warning: failed to parse key '%s'", origin) log.warn(" %s", e) continue log("u2f: trying to load DER public key %s", repr(key)) if not key.startswith(PUB_KEY_DER_PREFIX): key = PUB_KEY_DER_PREFIX + key try: k = load_der_public_key(key, default_backend()) except Exception as e: log("load_der_public_key(%r)", key, exc_info=True) log.warn("Warning: failed to parse key '%s'", origin) log.warn(" %s", e) continue self.public_keys[origin] = k if not self.public_keys: raise Exception( "u2f authenticator requires at least one public key")
def check(self, password): try: if WIN32: import winkerberos as kerberos #@UnresolvedImport @UnusedImport else: import kerberos #@UnresolvedImport @Reimport except ImportError as e: log("check(..)", exc_info=True) log.warn("Warning: cannot use kerberos password authentication:") log.warn(" %s", e) return False try: kerberos.checkPassword(self.username, password, self.service, self.realm) return True except kerberos.KrbError as e: log("check(..)", exc_info=True) log.error("Error: kerberos authentication failed:") log.error(" %s", e) return False
def __init__(self, username, **kwargs): log("hosts.Authenticator(%s, %s)", username, kwargs) if not POSIX: log.warn("Warning: hosts authentication is not supported on %s", os.name) return connection = kwargs.get("connection", None) try: from xpra.net.bytestreams import SocketConnection if not connection and isinstance(connection, SocketConnection): raise Exception("hosts: invalid connection '%s' (not a socket connection)" % connection) info = connection.get_info() log("hosts.Authenticator(..) connection info=%s", info) host = info.get("remote")[0] peername = info.get("endpoint")[0] except Exception as e: log.error("Error: cannot get host from connection") log.error(" %s", e) raise self.peername = peername self.host = host super().__init__(username, **kwargs)
def main(argv): from xpra.platform import program_context from xpra.log import enable_color with program_context("Auth-Test", "Auth-Test"): enable_color() for x in ("-v", "--verbose"): if x in tuple(argv): log.enable_debug() argv.remove(x) if len(argv) != 3: log.warn("invalid number of arguments") log.warn("usage: %s [--verbose] username password", argv[0]) return 1 username = argv[1] password = argv[2] a = Authenticator(username=username) if a.check(password): log.info("authentication succeeded") return 0 log.error("authentication failed") return 1
def emsg(e): try: log.warn(" LDAP Error: %s", e.message["desc"]) if "info" in e.message: log.warn(" %s", e.message["info"]) except: #python3: no way to get to the message dict? log.warn(" %s", e)
def check_peercred(self, connection, uids="", gids="", allow_owner=False): allow_uids = allow_gids = None if uids or allow_owner: allow_uids = [] if allow_owner: allow_uids.append(getuid()) for x in uids.split(":"): if not x.strip(): continue x = osexpand(x.strip()) try: allow_uids.append(int(x)) except ValueError: import pwd #pylint: disable=import-outside-toplevel try: pw = pwd.getpwnam(x) allow_uids.append(pw.pw_uid) except KeyError: log.warn("Warning: unknown username '%s'", x) log("peercred: allow_uids(%s)=%s", uids, allow_uids) if gids: allow_gids = [] for x in gids.split(":"): if not x.strip(): continue x = osexpand(x.strip()) try: allow_gids.append(int(x)) except ValueError: gid = get_group_id(x) if gid >= 0: allow_gids.append(gid) else: log.warn("Warning: unknown group '%s'", x) log("peercred: allow_gids(%s)=%s", gids, allow_gids) self.do_check_peercred(connection, allow_uids, allow_gids)
def __init__(self, username, **kwargs): log("peercred.Authenticator(%s, %s)", username, kwargs) if not POSIX: log.warn("Warning: peercred authentication is not supported on %s", os.name) return self.uid = -1 self.gid = -1 self.peercred_check = False connection = kwargs.get("connection", None) uids = kwargs.pop("uid", None) gids = kwargs.pop("gid", None) allow_uids = None allow_gids = None if uids: allow_uids = [] for x in uids.split(","): x = osexpand(x.strip()) try: allow_uids.append(int(x)) except ValueError: import pwd try: pw = pwd.getpwnam(x) uids.append(pw.pw_uid) except KeyError: log.warn("Warning: unknown username '%s'", x) log("peercred: allow_uids(%s)=%s", uids, allow_uids) if gids: allow_gids = [] for x in gids.split(","): x = osexpand(x.strip()) try: allow_gids.append(int(x)) except ValueError: gid = get_group_id(x) if gid >= 0: allow_gids.append(gid) else: log.warn("Warning: unknown group '%s'", x) log("peercred: allow_gids(%s)=%s", gids, allow_gids) try: from xpra.net.bytestreams import SocketConnection if connection and isinstance(connection, SocketConnection): sock = connection._socket peercred = get_peercred(sock) log("get_peercred(%s)=%s", sock, peercred) if not peercred: log.warn("Warning: failed to get peer credentials on %s", sock) return _, uid, gid = peercred if allow_uids is not None and uid not in allow_uids: log.warn("Warning: peercred access denied,") log.warn(" uid %i is not in the whitelist: %s", uid, csv(allow_uids)) elif allow_gids is not None and gid not in allow_gids: log.warn("Warning: peercred access denied,") log.warn(" gid %i is not in the whitelist: %s", gid, csv(allow_gids)) else: self.peercred_check = True self.uid = uid self.gid = gid else: log( "peercred: invalid connection '%s' (not a socket connection)", connection) except Exception as e: log.error("Error: cannot get peer uid") log.error(" %s", e) SysAuthenticator.__init__(self, username, **kwargs)