Skip to content

Commit

Permalink
MDL-35238 Implement HTTP authorization based on passphrase matching
Browse files Browse the repository at this point in the history
  • Loading branch information
mudrd8mz committed Nov 8, 2012
1 parent 11c3c57 commit c57f18a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
61 changes: 61 additions & 0 deletions mdeploy.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

class invalid_coding_exception extends Exception {}
class missing_option_exception extends Exception {}
class unauthorized_access_exception extends Exception {}


// Various support classes /////////////////////////////////////////////////////
Expand Down Expand Up @@ -100,8 +101,11 @@ final protected function __clone() {
*/
class input_manager extends singleton_pattern {

const TYPE_FILE = 'file'; // File name
const TYPE_FLAG = 'flag'; // No value, just a flag (switch)
const TYPE_INT = 'int'; // Integer
const TYPE_PATH = 'path'; // Full path to a file or a directory
const TYPE_RAW = 'raw'; // Raw value, keep as is

/** @var input_cli_provider|input_http_provider the provider of the input */
protected $inputprovider = null;
Expand Down Expand Up @@ -151,9 +155,12 @@ public function get_option($name, $default = 'provide_default_value_explicitly')
public function get_option_info($name=null) {

$supportedoptions = array(
array('d', 'dataroot', input_manager::TYPE_PATH, 'Full path to the dataroot (moodledata) directory'),
array('h', 'help', input_manager::TYPE_FLAG, 'Prints usage information'),
array('i', 'install', input_manager::TYPE_FLAG, 'Installation mode'),
array('u', 'upgrade', input_manager::TYPE_FLAG, 'Upgrade mode'),
array('', 'passfile', input_manager::TYPE_FILE, 'File name of the passphrase file (HTTP access only)'),
array('', 'password', input_manager::TYPE_RAW, 'Session passphrase (HTTP access only)'),
);

if (is_null($name)) {
Expand Down Expand Up @@ -217,12 +224,31 @@ public function cast_value($raw, $type) {

switch ($type) {

case input_manager::TYPE_FILE:
$raw = preg_replace('~[[:cntrl:]]|[&<>"`\|\':\\\\/]~u', '', $raw);
$raw = preg_replace('~\.\.+~', '', $raw);
if ($raw === '.') {
$raw = '';
}
return $raw;

case input_manager::TYPE_FLAG:
return true;

case input_manager::TYPE_INT:
return (int)$raw;

case input_manager::TYPE_PATH:
$raw = str_replace('\\', '/', $raw);
$raw = preg_replace('~[[:cntrl:]]|[&<>"`\|\':]~u', '', $raw);
$raw = preg_replace('~\.\.+~', '', $raw);
$raw = preg_replace('~//+~', '/', $raw);
$raw = preg_replace('~/(\./)+~', '/', $raw);
return $raw;

case input_manager::TYPE_RAW:
return $raw;

default:
throw new invalid_coding_exception('Unknown option type.');

Expand Down Expand Up @@ -563,6 +589,7 @@ public function execute() {
}

// Authorize access. None in CLI. Passphrase in HTTP.
$this->authorize();

// Fetch the ZIP file into a temporary location.

Expand All @@ -580,6 +607,40 @@ protected function initialize() {
$this->input = input_manager::instance();
$this->output = output_manager::instance();
}

// End of external API

/**
* Authorize access to the script.
*
* In CLI mode, the access is automatically authorized. In HTTP mode, the
* passphrase submitted via the request params must match the contents of the
* file, the name of which is passed in another parameter.
*
* @throws unauthorized_access_exception
*/
protected function authorize() {

if (PHP_SAPI === 'cli') {
return;
}

$dataroot = $this->input->get_option('dataroot');
$passfile = $this->input->get_option('passfile');
$password = $this->input->get_option('password');

$passpath = $dataroot.'/temp/mdeploy/'.$passfile;

if (!is_readable($passpath)) {
throw new unauthorized_access_exception('Unable to read passphrase file.');
}

$stored = file_get_contents($passpath);

if ($password !== $stored) {
throw new unauthorized_access_exception('Session passphrase does not match the stored one.');
}
}
}


Expand Down
8 changes: 8 additions & 0 deletions mdeploytest.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ public function data_for_cast_value() {
array('1', input_manager::TYPE_FLAG, true),
array('0', input_manager::TYPE_FLAG, true),
array('muhehe', input_manager::TYPE_FLAG, true),

array('C:\\WINDOWS\\user.dat', input_manager::TYPE_PATH, 'C/WINDOWS/user.dat'),
array('../../../etc/passwd', input_manager::TYPE_PATH, '/etc/passwd'),
array('///////.././public_html/test.php', input_manager::TYPE_PATH, '/public_html/test.php'),

array("!@#$%|/etc/qwerty\n\n\t\n\r", input_manager::TYPE_RAW, "!@#$%|/etc/qwerty\n\n\t\n\r"),

array("\nrock'n'roll.mp3\t.exe", input_manager::TYPE_FILE, 'rocknroll.mp3.exe'),
);
}

Expand Down

0 comments on commit c57f18a

Please sign in to comment.