[[Image(https://xpra.org/icons/authentication.png)]] = Authentication = [[BR]] {{{#!div class="box" == Introduction == Version 1.0 also supports SSL (see #1252) which can be used for authentication using certificates (see #1252). When using ssh to connect to a server, [/wiki/Encryption encryption] and authentication can be skipped (by default the unix domain sockets used by ssh do not use authentication). Xpra's authentication modules can be useful for: * securing socket connections * making the unix domain socket accessible to other users safely * using the [/wiki/ProxyServer Proxy Server] mode For more information on the different types of connections, see [/wiki/Network]. }}} {{{#!div class="box" == Modules == Starting with version 4.0, the preferred way of specifying authentication is within the socket option itself, ie for TCP: {{{ xpra start --start=xterm -d auth --bind-tcp=0.0.0.0:10000,auth=file:filename=password.txt }}} So that multiple sockets can use different authentication modules, and those modules can more easily be chained: {{{ xpra start --start=xterm -d auth \ --bind-tcp=0.0.0.0:10000,auth=hosts,auth=file:filename=password.txt --bind --bind-tcp=0.0.0.0:10001,auth=sys }}} ---- For older versions, the authentication modules used are specified using * {{{--auth=MODULE}}} for unix domain sockets and named pipes * {{{--tcp-auth=MODULE}}} for TCP sockets * {{{--vsock-auth=MODULE}}} for vsock (#983) etc For more information on the different modules, f. e. ssl, see [/wiki/Network/#Examples]. With version 2.3 and later, you may specify more than one module. ie: {{{--tcp-auth=hosts --tcp-auth=sqlite}}} will verify "hosts" (aka "TCP Wrappers") before checking the sqlite database. (see #1728 for details) [[BR]] Here are the modules that can be used: ||= Module =||= Result =||= Purpose =||= Version requirements =|| ||[/browser/xpra/trunk/src/xpra/server/auth/allow_auth.py allow]||always allows the user to login, the username used is the one supplied by the client||dangerous / only for testing|| || ||[/browser/xpra/trunk/src/xpra/server/auth/none_auth.py none]||always allows the user to login, the username used is the one the server is running as||dangerous / only for testing|| || ||[/browser/xpra/trunk/src/xpra/server/auth/fail_auth.py fail]||always fails authentication, no password required||useful for testing|| || ||[/browser/xpra/trunk/src/xpra/server/auth/reject_auth.py reject]||always fails authentication, pretends to ask for a password||useful for testing|| || ||[/browser/xpra/trunk/src/xpra/server/auth/env_auth.py env]||matches against an environment variable ({{{XPRA_PASSWORD}}} by default)||alternative to file module|| || ||[/browser/xpra/trunk/src/xpra/server/auth/password_auth.py password]||matches against a password given as a module option, ie: {{{auth=password:value=mysecret}}}||alternative to file module|| || ||[/browser/xpra/trunk/src/xpra/server/auth/multifile_auth.py multifile]||matches usernames and passwords against an authentication file||proxy: see [/wiki/Authentication#PasswordFile below]|| || ||[/browser/xpra/trunk/src/xpra/server/auth/file_auth.py file]||compares the password against the contents of a password file, see [/wiki/Authentication#PasswordFile below]||simple password authentication|| || ||[/browser/xpra/trunk/src/xpra/server/auth/pam.py pam]||linux PAM authentication||Linux system authentication|| || ||[/browser/xpra/trunk/src/xpra/server/auth/win32_auth.py win32]||win32security authentication||MS Windows system authentication|| || ||{{{sys}}}||system authentication||virtual module which will choose win32 or pam authentication automatically|| || ||[/browser/xpra/trunk/src/xpra/server/auth/sqlite_auth.py sqlite]||sqlite database authentication||see ticket:1488#comment:37 || >=2.1|| ||[/browser/xpra/trunk/src/xpra/server/auth/peercred_auth.py peercred]||SO_PEERCRED authentication||see r15886 || >=2.1|| ||[/browser/xpra/trunk/src/xpra/server/auth/hosts_auth.py hosts]||[https://en.wikipedia.org/wiki/TCP_Wrapper TCP Wrapper]||see #1730 || >=2.3|| ||[/browser/xpra/trunk/src/xpra/server/auth/exec_auth.py exec]||Delegates to an external command||see ticket:1690#comment:4 || >=2.3|| ||[/browser/xpra/trunk/src/xpra/server/auth/kerberos_password_auth.py kerberos-password]||Uses kerberos to authenticate a username + password||see ticket:1691#comment:4 || >=2.3|| ||[/browser/xpra/trunk/src/xpra/server/auth/kerberos_ticket_auth.py kerberos-ticket]||Uses a kerberos ticket to authenticate a client||see ticket:1691#comment:4 || >=2.3|| ||[/browser/xpra/trunk/src/xpra/server/auth/gss_auth.py gss]||Uses a GSS ticket to authenticate a client||see ticket:1691#comment:4 || >=2.3|| ||[/browser/xpra/trunk/src/xpra/server/auth/ldap_auth.py ldap]||Uses ldap via [https://www.python-ldap.org/en/latest/ python-ldap]||see #1791|| >=2.3|| ||[/browser/xpra/trunk/src/xpra/server/auth/ldap3_auth.py ldap]||Uses ldap via [https://github.com/cannatag/ldap3 python-ldap3]||see #1791|| >=2.3|| ||[/browser/xpra/trunk/src/xpra/server/auth/u2f_auth.py u2f]||[https://en.wikipedia.org/wiki/Universal_2nd_Factor Universal 2nd Factor]||see #1789 || >=2.3|| [[BR]] == usernames == The username can be specified in the connection files you can save from the launcher, or in the client connection string, ie for tcp: {{{ xpra attach tcp://username:password@host:port/ }}} When an authentication module is used to secure a single session, many modules will completely ignore the username part and it can be omitted from the connection string. ie for tcp: {{{ xpra attach tcp://:password@host:port/ }}} Or even replaced with any string of your liking, ie 'foobar': {{{ xpra attach tcp://foobar:password@host:port/ }}} Only the following modules will make use of both the username and password to authenticate against their respective backend: {{{kerberos-password}}}, {{{ldap}}}, {{{ldap3}}}, {{{sys}}} ({{{pam}}} and {{{win32}}}), {{{sqlite}}}, {{{multifile}}} and {{{u2f}}}. In this case, using an invalid username will cause the authentication to fail. The username is more important when authenticating against the [/wiki/ProxyServer] (see authentication details there). }}} {{{#!div class="box" == Module Options == The same module may be used with different types of sockets (tcp-auth vs auth), each with a different set of options. For more details see ticket:1159#comment:1. Some examples: * {{{XPRA_PASSWORD=mysecret xpra start --auth=env}}} * {{{SOME_OTHER_ENV_VAR_NAME=mysecret xpra start --auth=env:name=SOME_OTHER_ENV_VAR_NAME}}} * {{{xpra start --auth=password:value=mysecret}}} * {{{xpra start --auth=file:filename=/path/to/mypasswordfile.txt}}} * {{{xpra start --auth=sqlite:filename=/path/to/userlist.sdb}}} Beware when mixing environment variables and password files as the latter may contain a trailing newline character whereas the former often do not. }}} {{{#!div class="box" == Password File == "file" vs "multifile": * "file" contains a single password, the whole file is the password * "multifile" contains a list of authentication values, see [/wiki/ProxyServer#FileAuthenticationExtras proxy server file authentication] - this module is deprecated in favour of "sqlite" #1488 which is easier to configure. }}} {{{#!div class="box" == Authentication Process == The steps below assume that the client and server have been configured to use authentication: * If the server is not configured for authentication, the client connection should be accepted and a warning will be printed * If the client is not configured for authentication, a password dialog may show up, and the connection will fail with an authentication error if the correct value is not supplied [[BR]] == Notes == * This information applies to all clients: regular GUI clients as well as command line clients like "xpra info" * Each authentication module specifies the type of password hashing it supports (usually [https://en.wikipedia.org/wiki/Hash-based_message_authentication_code HMAC]) * Some authentication modules ({{{pam}}}, {{{win32}}}, {{{kerberos-password}}}, {{{ldap}}} and {{{ldap3}}}) require the actual password to be sent across to perform the authentication on the server - they therefore use the weak "xor" hashing * You must use [/wiki/Encryption] to be able to use "xor" hashing so that the password is protected during the exchange: the system will refuse to send a "xor" hashed password unencrypted * Encryption is processed before authentication For more information on packets, see [/wiki/NetworkProtocol]. [[BR]] == Negotiation == * All clients first send a ''hello'' packet to the server. If the client expects the server to request authentication for the connection, the client packet may omit most of the regular configuration information since a second packet will need to be sent. Until the server accepts the connection with its own ''hello'' packet response, the only packets that will be accepted by the clients are ''challenge'' and ''set_deflate'' (used to control packet compression). The client will exit unless the server responds within the {{{XPRA_SOCKET_TIMEOUT}}} delay + 10 seconds. * The server sends back a ''challenge'' packet containing a random salt and the digest method to use as specified by the authentication module. If the client does not respond within the {{{XPRA_SOCKET_TIMEOUT}}} delay (defaults to 10 seconds), it is disconnected. The only packets that will be accepted by the server until the client has successfully authenticated are ''hello'' and ''disconnect''. * The client generates its own random salt and responds with a new "hello" packet containing the challenge response (the hashed password and the client salt used), the client and server salts are combined before hashing the password. (so there is no way for the server or client to predict the actual salt used) * When the server receives the ''hello'' packet containing the challenge response, it hands it over to the authentication module, which can then: * with ''hmac'': verify that it obtains the same hash by combining its own password value with the two salts * with ''xor'': xor the password again with the two salts to retrieve the original password value * these steps may be repeated if there is more than one authentication module configured (though not all authentication modules require a challenge exchange) }}} {{{#!div class="box" == Security Considerations == * when used over TCP sockets, password authentication is vulnerable to man-in-the-middle attacks where an attacker could intercept the initial exchange and use the stolen authentication challenge response to access the session, [/wiki/Encryption Encryption] prevents that * the client does not verify the authenticity of the server, [/wiki/Encryption Encryption] does * Enabling {{{auth}}} [/wiki/Logging] may leak some authentication information * if you are concerned about security, use SSH as transport instead [[BR]] == Salt handling is important == * [https://crypto.stackexchange.com/a/34162/48758 64-bit entropy is nowhere near enough against a serious attacker]: ''If you want to defend against rainbow tables, salts are inevitable, because you need a full rainbow table per unique salt, which is computationally and storage-wise intense'' * [https://blog.mozilla.org/security/2011/05/10/sha-512-w-per-user-salts-is-not-enough/ SHA-512 w/ per User Salts is Not Enough]: ''In the event the hash was disclosed or the database was compromised, the attacker will already have one of the two values (i.e. the salt), used to construct the hash'' * [https://news.ycombinator.com/item?id=1998198 about hmac]: ''Those people should know that HMAC is as easy to precompute as naked SHA1 is; you can "rainbow-table" HMAC'' * we got it wrong before: r16967 }}}