the fast, reliable localhost tunneling solution


DNS-Based Authentication

By Tito Brasolin 2012-12-10, 09:01

PyPagekite allows front-ends to delegate authentication to a remote service according to a DNS-based authentication protocol. The command line option --authdomain is documented here.

If you are not familiar with DNS requests and responses, just play around with your Python console and socket.gethostbyname_ex(hostname)

import socket
socket.gethostbyname_ex('mail.google.com')

The answer should look like this:

('googlemail.l.google.com', ['mail.google.com'], ['173.194.35.21', '173.194.35.22'])
  • 'googlemail.l.google.com' (hostname) is the primary host name;
  • ['mail.google.com'] (aliaslist) is a list of alternative host names;
  • ['173.194.35.21', '173.194.35.22'] (ipaddrlist) is a list of IPv4 addresses for the same interface on the same host.

DNS Lookup

If the front-end is running with --authdomain=myauthdomain.com a lookup string may look like this:

(srand).(token).(sign).http.myname.example.com.myauthdomain.com
  • 'http' (protoport) A protocol may also be explicitly bound to a particular port by appending a dash and the decimal port number (e.g. http-80 or raw-22).
  • 'myname.example.com' (domain) May be any arbitrary DNS domain name.
  • '(srand)' A 36 character random salt generated by the PageKite back-end.
  • '(token)' A 36 character random salt generated by the PageKite front-end.
  • '(sign)' A 36 character shared-secret-based signature of all previous fields. See here for details on how this is calculated.
  • 'myauthdomain.com' (adom) Authentication domain.

When a back-end is connecting, the front-end queries the DNS server and extracts authentication errors and extended quota info from CNAME replies.

(hn, al, ips) = socket.gethostbyname_ex(lookup)

The primary hostname is splitted into error, days and connections informations:

if al:
  error, hg, hd, hc, junk = hn.split('.', 4)
  q_days = int(hd, 16)
  q_conns = int(hc, 16)
else:
  error = q_days = q_conns = None

A few constants are defined in common.py

AUTH_ERRORS           = '255.255.255.'
AUTH_ERR_USER_UNKNOWN = '.0'
AUTH_ERR_INVALID      = '.1'

If ips[0] starts with '255.255.255.' then an authentication error just happened: the user may be unknown (ips[0] ends with '.0') or invalid (ips[0] ends with '.1').

Otherwise the user has been authenticated and the quota is encoded in the IP. Look at LookupDomainQuota to see how it works.

Comments

  1. Michiel de Jong said on 2016-06-01, 14:05
    The link to LookupDomainQuota should be https://github.com/pagekite/PyPagekit... (line numbers have shifted)
    Permalink

Leave a comment

( (Please leave these blank: )

We use Gravatar for commenter's photos. Get your own, it's free!