Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Enhance the plugable authentication system
  • Loading branch information
DaveWoodCom committed Jan 26, 2020
1 parent 9bad839 commit e16e336
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 45 deletions.
10 changes: 8 additions & 2 deletions auth/none/none.php
Expand Up @@ -9,11 +9,17 @@
// uses OAuth etc.

// You must include a function with this signature.
// Return true/false if the username/password is a valid combination.
function isValidUser($username, $password) {
// Return true/false if the current user is a valid user.
function isValidUser() {
return true;
}

// You must include a function with this signature.
// Return an associated array with name/value pairs to be appended to OTAgo URLs (to pass the authentication through).
function queryStringAuthParameters() {
return array();
}

// You must include a function with this signature.
// Send a response to trigger an authentication request, then exit.
function requestAuthentication() {
Expand Down
161 changes: 153 additions & 8 deletions auth/simple/simpleAuth.php
Expand Up @@ -8,20 +8,45 @@
// You can swap in an alternate authentication system that connects to a database, or
// uses OAuth etc.

if (!isset($users)) {
$users = array();
}
/////////////////////////////////////////////////////////////////////////////////////////
// Required Functions
/////////////////////////////////////////////////////////////////////////////////////////

// You must include a function with this signature.
// Return true/false if the username/password is a valid combination.
function isValidUser($username, $password) {
// Return true/false if the current user is a valid user.
function isValidUser() {
global $users;

if (empty($username) || empty($password)) {
global $username;
global $password;
global $requestUUID;

if (empty($username)) {
return false;
}

return $users[$username] == $password;
if ($users[$username] == $password) {
touch(userTokenFilename());
return true;
}
else if (file_exists(userTokenFilename())) {
return true;
}

return false;
}

// You must include a function with this signature.
// Return an associated array with name/value pairs to be appended to OTAgo URLs (to pass the authentication through).
function queryStringAuthParameters() {
global $username;
global $requestUUID;

$parameters = array(
'u' => $username,
't' => $requestUUID,
);

return $parameters;
}

// You must include a function with this signature.
Expand All @@ -30,3 +55,123 @@ function requestAuthentication() {
requestBasicAuthentication('Authentication Required');
exit;
}

/////////////////////////////////////////////////////////////////////////////////////////
// Configuration Options
/////////////////////////////////////////////////////////////////////////////////////////

// You shouldn't need to change these under normal conditions, but you can if you need to
// (if you're using multiple OTAgo set ups with the same temp directory for example).
// To change these, add them to your configuration.php file, don't change them here.
if (!isset($simpleAuthTokenPrefix)) {
$simpleAuthTokenPrefix = 'simpleAuthToken';
}
if (!isset($simpleAuthTokenExtension)) {
$simpleAuthTokenExtension = 'otago';
}
if (!isset($simpleAuthTokenLifetime)) {
$simpleAuthTokenLifetime = 3600; // 1 hour (3600 seconds)
}
if (!isset($simpleAuthTempDirectory)) {
$simpleAuthTempDirectory = '/tmp';
}

/////////////////////////////////////////////////////////////////////////////////////////
// Supporting Functions
/////////////////////////////////////////////////////////////////////////////////////////

function initalizeRequest() {
global $users;
global $username;
global $password;
global $requestUUID;

if (!isset($users)) {
$users = array();
}

if (isset($_GET['u'])) {
$username = $_GET['u'];
}
if (empty($username) && isset($_SERVER['PHP_AUTH_USER'])) {
$username = $_SERVER['PHP_AUTH_USER'];
}

if (isset($_SERVER['PHP_AUTH_PW'])) {
$password = $_SERVER['PHP_AUTH_PW'];
}

if (isset($_GET['t'])) {
$requestUUID = $_GET['t'];
}
if (empty($requestUUID)) {
$requestUUID = randomUUID();
}
}

function randomUUID() {
$groups = array();

for ($i=0; $i<8; ++$i) {
if (function_exists('random_bytes')) {
$groups[] = bin2hex(random_bytes(2));
}
elseif (function_exists('mcrypt_create_iv')) {
$groups[] = bin2hex(mcrypt_create_iv(2, MCRYPT_DEV_URANDOM));
}
elseif (function_exists('openssl_random_pseudo_bytes')) {
$groups[] = bin2hex(openssl_random_pseudo_bytes(2));
}
}

return sprintf('%s%s-%s-%s-%s-%s%s%s', $groups[0], $groups[1], $groups[2], $groups[3], $groups[4], $groups[5], $groups[6], $groups[7]);
}

function userTokenFilename() {
global $username;
global $requestUUID;

global $simpleAuthTempDirectory;
global $simpleAuthTokenPrefix;
global $simpleAuthTokenExtension;

return sprintf('%s/%s_%s_%s.%s', $simpleAuthTempDirectory, $simpleAuthTokenPrefix, base64_encode($username), $requestUUID, $simpleAuthTokenExtension);
}

function cleanTempDir() {
global $simpleAuthTempDirectory;
global $simpleAuthTokenPrefix;
global $simpleAuthTokenExtension;
global $simpleAuthTokenLifetime;

$tempDir = dir($simpleAuthTempDirectory);
while (($filename = $tempDir->read()) !== false) {
$fullFilePath = $simpleAuthTempDirectory . '/' . $filename;
$extension = pathinfo($fullFilePath, PATHINFO_EXTENSION);

// Check file extension matches our expected value
if ($extension != $simpleAuthTokenExtension) {
continue;
}

// Check the file prefix matches our expected value
if (substr($filename, 0, strlen($simpleAuthTokenPrefix)) != $simpleAuthTokenPrefix) {
continue;
}

// Check if the file is
$fileAge = time() - filemtime($fullFilePath);
if ($fileAge < $simpleAuthTokenLifetime) {
continue;
}

unlink($fullFilePath);
}
$tempDir->close();
}

/////////////////////////////////////////////////////////////////////////////////////////
// Initialize Request
/////////////////////////////////////////////////////////////////////////////////////////
initalizeRequest();
cleanTempDir();
11 changes: 11 additions & 0 deletions common.php
Expand Up @@ -18,3 +18,14 @@ function requestBasicAuthentication($realm) {
http_response_code(401);
exit;
}

function makeURLQueryString($parameters, $joinString) {
$pairs = array();

foreach ($parameters as $name => $value) {
$pairs[] = urlencode($name) . '=' . urlencode($value);
}

return implode($joinString, $pairs);
}

15 changes: 12 additions & 3 deletions configuration.default.php
Expand Up @@ -4,18 +4,27 @@
// - https://github.com/DaveWoodCom/OTAgo
// - Copyright 2020 Dave Wood, Cerebral Gardens Inc.

// Authentication
// Choose one authentication method
// Current options: None, or Simple Auth

// Authentication - None
// $authFile = 'auth/none/none.php';

// Authentication - Simple Auth
$authFile = 'auth/simple/simpleAuth.php';
$simpleAuthTempDirectory = '/tmp';
$simpleAuthTokenLifetime = 3600; // 1 hour (3600 seconds)
$users = array(
'dave' => 'secr3t',
'john' => 'hunter2'
);

// Web Template
// Templates
// -- Web
$webTemplate = 'templates/webTemplate.html';
$installURLPlacehHolder = '{{InstallURL}}';

// Manifest
// -- Manifest
$manifestTemplate = 'templates/manifest.plist';
$ipaURLPlacehHolder = '{{IPAURL}}';

Expand Down
11 changes: 1 addition & 10 deletions ipa.php
Expand Up @@ -13,18 +13,9 @@
}
require_once($authFile);

$username = $_GET['u'];
$password = $_GET['p'];
if (empty($username)) {
$username = $_SERVER['PHP_AUTH_USER'];
}
if (empty($password)) {
$password = $_SERVER['PHP_AUTH_PW'];
}

preventCaching();

if (!isValidUser($username, $password)) {
if (!isValidUser()) {
requestAuthentication();
exit();
}
Expand Down
13 changes: 2 additions & 11 deletions manifest.php
Expand Up @@ -13,25 +13,16 @@
}
require_once($authFile);

$username = $_GET['u'];
$password = $_GET['p'];
if (empty($username)) {
$username = $_SERVER['PHP_AUTH_USER'];
}
if (empty($password)) {
$password = $_SERVER['PHP_AUTH_PW'];
}

preventCaching();

if (!isValidUser($username, $password)) {
if (!isValidUser()) {
requestAuthentication();
exit();
}

$manifest = file_get_contents($manifestTemplate);

$ipaURL = $baseURL . 'ipa.php?u=' . urlencode($username) . '&amp;p=' . urlencode($password);
$ipaURL = $baseURL . 'ipa.php?' . makeURLQueryString(queryStringAuthParameters(), '&amp;');
$manifest = str_replace($ipaURLPlacehHolder, $ipaURL, $manifest);

echo $manifest;
13 changes: 2 additions & 11 deletions protected.php
Expand Up @@ -13,25 +13,16 @@
}
require_once($authFile);

$username = $_GET['u'];
$password = $_GET['p'];
if (empty($username)) {
$username = $_SERVER['PHP_AUTH_USER'];
}
if (empty($password)) {
$password = $_SERVER['PHP_AUTH_PW'];
}

preventCaching();

if (!isValidUser($username, $password)) {
if (!isValidUser()) {
requestAuthentication();
exit();
}

$html = file_get_contents($webTemplate);

$manifestURL = $baseURL . 'manifest.php?u=' . urlencode($username) . '&p=' . urlencode($password);
$manifestURL = $baseURL . 'manifest.php?' . makeURLQueryString(queryStringAuthParameters(), '&');
$installURL = 'itms-services://?action=download-manifest&url=' . urlencode($manifestURL);

$html = str_replace($installURLPlacehHolder, $installURL, $html);
Expand Down

0 comments on commit e16e336

Please sign in to comment.