BitsDevelopmentTeam/bits-server — pull request #22 by esseks (2014-10-21 21:58:49+00:00)
Title: Macroster

The list of users who are in the headquarter will be shown in the private area of the site. This is a nice feature for other members to know whether someone they are looking for is currently available.

Presences are inferred from MAC addresses, which are harvested by an external script and submitted via the new API call `/macupdate`. HTTP requests to `/macupdate` must be issued via POST and two parameters must be included:

* `password`: an authentication token shared between BITS server and remote updater. It can be set using the `mac_update_password` config option and defaults to `"default"`.
* `mac`: a JSON-encoded array of hashed mac addresses.

A wrong passwords generates a 403 (not authorized) error, while a malformed request (one or both parameters missing) generates a 400 (malformed request) error.

If the password issued by the client matches, BITS will query the users to whom the harvested MAC addresses are associated and update the roster view in the private area. For establishing a relationship between users and mac addresses, a `MACToUser(mac_hash, userid)` table has been created.

Calls to `/macupdate` are rate limited and the minimum delta between updates can be configured using the `mac_update_interval` option. The limit is global, since only one harvester should be submitting data.

In order to guarantee reasonable privacy to users, MAC addresses are hashed before being submitted to `/macupdate`. Since the preimage space for this problem is really small, a secret part is introduced in the hash by using a HMAC-SHA256 function:

def hash(mac):
return hmac.new(SECRET_KEY, mac, hashlib.sha256).hexdigest()

the `SECRET_KEY` is not known to `bits-server` and it is not stored on the server. Only hashes are stored in the DB and sent through the wire. The exact format of `mac` is not even relevant for `bits-server` to match hashes, as long as the harvester always generates the same hash for same MAC.