xpra icon
Bug tracker and wiki

Opened 9 months ago

Closed 3 months ago

#1691 closed enhancement (worksforme)

kerberos authentication

Reported by: Antoine Martin Owned by: J. Max Mena
Priority: major Milestone: 2.3
Component: network Version: trunk
Keywords: Cc:

Description (last modified by Antoine Martin)

Looks like we can use pykerberos, if only there were better examples.

See also #1255, #1692

Attachments (1)

winkerberos-mingw.patch (1.6 KB) - added by Antoine Martin 5 months ago.
patch for building with mingw

Download all attachments as: .zip

Change History (11)

comment:1 Changed 9 months ago by Antoine Martin

Description: modified (diff)
Milestone: 2.22.3
Status: newassigned

comment:2 Changed 5 months ago by Antoine Martin

Added dumb implementation in r18693 using pykerberos.

Going forward, we should use the tokens rather than the password, and maybe even use python-gssapi for encryption?

comment:3 Changed 5 months ago by Antoine Martin

Based on centos 6: configuring a kerberos 5 server, and made harder by the fact that my LAN doesn't have a domain or DNS server...

hostname localdomain
/usr/sbin/kdb5_util create -s
cat > /etc/krb5.conf << EOF
includedir /etc/krb5.conf.d/

 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

 dns_lookup_realm = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 rdns = false
 default_ccache_name = KEYRING:persistent:%{uid}
 default_realm = LOCALDOMAIN

  kdc = localhost
  admin_server = localhost

 localdomain = LOCALDOMAIN
echo "*/admin@LOCALDOMAIN	*" > /var/kerberos/krb5kdc/kadm5.acl 
kadmin.local -q "addprinc test/admin"
kinit admin
kadmin -q "addprinc xpra"

The python-gssapi documentation at https://pythonhosted.org/python-gssapi/examples.html is out of date, but this one isn't: https://pythongssapi.github.io/python-gssapi/latest/gssapi.html.

For win32, we could use winkerberos instead of pykerberos.

  • with gssapi:


$ python
import gssapi
service_name = gssapi.Name("xpra")
ctx = gssapi.SecurityContext(name=service_name, usage="initiate")
k = ctx.step()


from gssapi import creds as gsscreds
from gssapi import sec_contexts as gssctx

server_creds = gsscreds.Credentials(usage='accept')
server_ctx = gssctx.SecurityContext(creds=server_creds)
  • with kerberos:


v,c = kerberos.authGSSClientInit("xpra")
assert v==1
kerberos.authGSSClientStep(c, "")
k = kerberos.authGSSClientResponse(c)


v,c = kerberos.authGSSServerInit("xpra")
assert v==1
r = kerberos.authGSSServerStep(c, k)
assert r==1

Things to think about:

Last edited 5 months ago by Antoine Martin (previous) (diff)

comment:4 Changed 5 months ago by Antoine Martin

The overloading of the "digest" list to add and detect support for "kerberos" and "gss" options is a bit ugly, but it is the most backwards compatible way. Older clients will just state that they don't support "kerberos" (or "gss") rather than failing in more obscure ways.


xpra start --start-child="xterm" --bind-tcp= --tcp-auth=kerberos-token,service=xpra
xpra start --start-child="xterm" --bind-tcp= --tcp-auth=gss,service=xpra


  • packaging: builds and package libs for win32 (tricky: won't build) and macos
  • clients should be able to configure authentication: all|gui|tui|none|kerberos|gss
  • support multiple steps in auth modules (kerberos and gss may take multiple steps)
  • lots of testing, ideally against MS AD
  • add mutual authentication
  • security review
  • unit tests (hard!)
Last edited 5 months ago by Antoine Martin (previous) (diff)

Changed 5 months ago by Antoine Martin

Attachment: winkerberos-mingw.patch added

patch for building with mingw

comment:5 Changed 5 months ago by Antoine Martin

On win32, building winkerberos requires patching the header file to insert the missing SecPkgContext_Bindings structure definition then figuring out the equivallent gcc stanza for the msvc arguments. See patch attached, submitted upstream here: https://github.com/mongodb-labs/winkerberos/issues/21.

comment:6 Changed 5 months ago by Antoine Martin

Installing winkerberos from the modified source requires one more hack to prevent cx_freeze from messing up the packaging, as per stopping setup.py from installing as egg, we have to use pip to ensure it does not get installed as an egg:

pushd winkerberos-0.7.0
python2 setup.py sdist
pip2 install ./winkerberos-0.7.0/dist/winkerberos-0.7.0.tar.gz
pip3 install ./winkerberos-0.7.0/dist/winkerberos-0.7.0.tar.gz

comment:7 Changed 5 months ago by Antoine Martin

First, install gss support: r18758, ie on x86_64:

pacman -S mingw-w64-x86_64-gss

Building python-gssapi:

  • use the correct gss header filename: gss.h with MSYS2 and not gssapi/gssapi.h:
    sed -i -e 's+gssapi/gssapi.h+gss.h+g' gssapi/raw/python_gssapi.h
    sed -i -e 's+gssapi/gssapi.h+gss.h+g' gssapi/raw/python_gssapi_ext.h
    sed -i -e 's+gssapi/gssapi_krb5.h+gss.h+g' gssapi/raw/python_gssapi_krb5.h
  • then we need to add the missing gss_mech_krb5 in gssapi/raw/mech_krb5.pyx:
    cdef extern from "python_gssapi_krb5.h":
    def make_OID(s):
        import struct
        v = struct.pack("@Is", len(s), s)
        return v
    pkrb5 = make_OID(b"\x2A\x86\x48\x86\xF7\x12\x01\x02\x02")
    cdef char *gss_mech_krb5_str = pkrb5
    pprincipal = make_OID(b"\x2A\x86\x48\x86\xF7\x12\x01\x02\x02");
    cdef char *GSS_KRB5_NT_PRINCIPAL_NAME_str = pprincipal
    cdef gss_OID gss_mech_krb5 = <gss_OID> gss_mech_krb5_str

(and if I got this wrong, gss won't work...)

  • finally, find the magic incantation for the setup file:
    GSSAPI_MAIN_LIB=$MSYSTEM_PREFIX/bin/libgss-3.dll \
    GSSAPI_LINKER_ARGS="-lgss" \
    python2 ./setup.py install

(clean and repeat with python3)

  • with python3, one also needs to skip the prefix test in setup.py:
        prefix = get_output('krb5-config gssapi --prefix')
        prefix = ""

Changes submitted upstream: support building against mingw headers.

Last edited 5 months ago by Antoine Martin (previous) (diff)

comment:8 Changed 5 months ago by Antoine Martin

Lots of improvements in r18780 (see commit message).

Examples (add -d auth for debug):

  • to only use kerberos authentication and with a specific service name "xpra":
    XPRA_KERBEROS_SERVICES="xpra" xpra attach tcp://localhost:10000/ --challenge-handlers=kerberos
  • to use the GUI prompt only for password (the URI password will be ignored):
    xpra attach tcp://username:unusedpassword@localhost:10000/ --challenge-handlers=prompt
  • to use the XPRA_PASSWORD environment variable for the first challenge, then the URI one for the second (when using multiple tcp-auth arguments when starting the server):
    XPRA_PASSWORD=password1 xpra attach tcp://username:passwordno2@localhost:10000/ --challenge-handlers=env,uri

comment:9 Changed 5 months ago by Antoine Martin

Owner: changed from Antoine Martin to J. Max Mena
Status: assignednew


Ready for testing. There are packages for most platforms.

@maxmylyn: apart from testing the obvious command lines (ie: comment:8), the difficult thing is testing single-sign-on with gss / kerberos because this requires a domain controller on win32, and on macos: Authentication : kerberos
Please keep this ticket tidy as this will be the reference until the details are wiki-ized.

comment:10 Changed 3 months ago by Antoine Martin

Resolution: worksforme
Status: newclosed
Note: See TracTickets for help on using tickets.