Permalink
Browse files

MDL-35238 Implement HTTP authorization based on passphrase matching

  • Loading branch information...
1 parent 11c3c57 commit c57f18ad06558da0ebfb6c38fef05923701d9bbf @mudrd8mz mudrd8mz committed Sep 17, 2012
Showing with 69 additions and 0 deletions.
  1. +61 −0 mdeploy.php
  2. +8 −0 mdeploytest.php
View
@@ -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 /////////////////////////////////////////////////////
@@ -100,8 +101,11 @@ protected function initialize() {
*/
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;
@@ -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)) {
@@ -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.');
@@ -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.
@@ -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.');
+ }
+ }
}
View
@@ -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'),
);
}

0 comments on commit c57f18a

Please sign in to comment.