Version 10 (modified by 8 years ago) ( diff ) | ,
---|
Login Service
May First/People Link provides a web-based API for verifying login credentials called "login-service". It is designed to allow applications to verify that a given username and password is valid or that a given username exists.
In "check" mode it takes as input a username, password, and application id, and responds with either a no (indicating invalid) or a yes indicating a valid username and password or error.
In "user" mode it takes as input a username and application id, and responds with either a no (indicating the username doesn't exist) or a yes indicating a valid username or error.
Server side
The server is running a python twisted web application, available via git: git://git.mayfirst.org/mfpl/login-service. It is currently installed on hay.mayfirst.org in /usr/local/share/login-service, listens on port 8080, requires tls, and is configured to use the id.mayfirst.org key and certificate.
The application is managed by runit (via /etc/sv/login-service), so it should restart when the system restarts.
The application runs as the login-service unix user. It also has access to it's own mysql username and password (configured via files in /etc/sv/login-service/env) that grant it the privilege of logging into the MySQL server on hay and of executing the get_salt
and valid_hash
MySQL procedures that enable it to verify a username and password witout having access to the table of usernames and passwords.
One environment variable set via the file /etc/sv/login-service/env/LS_APP_IDS contains a space separated list of randomly generated strings that act as an application id. The idea is that each application that we configure to use the service will share a secret that is stored in this file. The shared secret helps prevent dictionary attacks against the service.
Client side
Writing a client to interface with the login service is relatively easy.
Bash
#!/bin/bash service="$1" app_id="$2" user="$3" pass="$4" if [ -z "$service" -o -z "$app_id" -o -z "$user" ]; then printf "Please pass service app_id and user as the first three arguments.\n" exit 2 fi if [ "$service" != "user" -a "$service" != "check" ]; then printf "Service must be user or check.\n" exit 2 fi if [ "$service" = "check" -a -z "$pass" ]; then printf "If you pass user as the service, the last argument should be a password.\n" exit 2 fi out=$(curl -s "https://id.mayfirst.org:8080/${service}?user=${user}&password=${pass}&app_id=${app_id}") [ "$out" = "yes" ] && exit 0 exit 1
Python
mayfirstAuth
is a simple python module (currently only installed on mcchesney
), source below. It allows a writer of any python script to easily query the login-service.
Usage:
#!/usr/bin/python from mayfirstAuth import check, user username = 'YOUR-USER-NAME' password = 'YOUR-PASSWORD' appid = 'YOUR-APP-ID' check = check(username, password, appid) user = user(username, appid) if check == "0": print 'Login success' else: print 'Login failure' if user == "0": print 'User exists' else: print 'User does not exist'
Source:
Save this file as mayfirstAuth.py in /usr/local/lib/python2.7/dist-packages
#!/usr/bin/python import requests # set the login service URL url = 'https://id.mayfirst.org:8080/' def check(username, password, appid): values = {'user' : username, 'password' : password, 'app_id' : appid} req = requests.post(url + "check", data=values) is_valid_user = req.text if is_valid_user == "yes": return "0" return "1" def user(username, appid): values = {'user' : username, 'app_id' : appid} req = requests.post(url + "user", data=values) is_valid_user = req.text if is_valid_user == "yes": return "0" return "1"
PHP
<?php // Fixme - only supports check not user. function authenticate_user($user, $password, $app_id) { $url = 'https://id.mayfirst.org:8080/check?user=' . urlencode($user) . '&password=' . urlencode($password) . '&app_id=' . $app_id; $out = file_get_contents($url); if($out == "yes") return TRUE; return FALSE; } ?>
While GET functions are easier to write, POST functions are less likely to log your password (on the client side - logging is disabled on the server side).
<?php // Fixme - only supports check not user. function authenticate_user($user, $password, $app_id) { $url = 'https://id.mayfirst.org:8080/check'; $vars = 'user=' . urlencode($user) . '&password=' . urlencode($password) . '&app_id=' . urlencode($app_id); $ch = curl_init( $url ); curl_setopt( $ch, CURLOPT_POST, 1); curl_setopt( $ch, CURLOPT_POSTFIELDS, $vars); curl_setopt( $ch, CURLOPT_HEADER, 0); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1); $response = curl_exec( $ch ); if($response == "yes") return TRUE; return FALSE; }