Search moodle.org's
Developer Documentation


Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
  •    1  <?php
       2  /**
       3   * An XML-RPC server
       4   *
       5   * @author  Donal McMullan  donal@catalyst.net.nz
       6   * @version 0.0.1
       7   * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
       8   * @package mnet
       9   */
      10  
      11  // Make certain that config.php doesn't display any errors, and that it doesn't
      12  // override our do-not-display-errors setting:
      13  // disable moodle specific debug messages and any errors in output
      14  define('NO_DEBUG_DISPLAY', true);
      15  // cookies are not used, makes sure there is empty global $USER
      16  define('NO_MOODLE_COOKIES', true);
      17  
      18  define('MNET_SERVER', true);
      19  
      20  require(__DIR__.'/../../config.php');
      21  
      22  $mnet = get_mnet_environment();
      23  // Include MNET stuff:
      24  require_once $CFG->dirroot.'/mnet/lib.php';
      25  require_once $CFG->dirroot.'/mnet/remote_client.php';
      26  require_once $CFG->dirroot.'/mnet/xmlrpc/serverlib.php';
      27  
      28  
      29  if ($CFG->mnet_dispatcher_mode === 'off') {
      30      print_error('mnetdisabled', 'mnet');
      31  }
      32  
      33  // Content type for output is not html:
      34  header('Content-type: text/xml; charset=utf-8');
      35  
      36  $rawpostdata = file_get_contents("php://input");
      37  mnet_debug("RAW POST DATA", 2);
      38  mnet_debug($rawpostdata, 2);
      39  
      40  if (!isset($_SERVER)) {
      41      exit(mnet_server_fault(712, get_string('phperror', 'mnet')));
      42  }
      43  
      44  
      45  // New global variable which ONLY gets set in this server page, so you know that
      46  // if you've been called by a remote Moodle, this should be set:
      47  $remoteclient = new mnet_remote_client();
      48  set_mnet_remote_client($remoteclient);
      49  
      50  try {
      51      $plaintextmessage = mnet_server_strip_encryption($rawpostdata);
      52      $xmlrpcrequest = mnet_server_strip_signature($plaintextmessage);
      53  } catch (Exception $e) {
      54      mnet_debug('encryption strip exception thrown: ' . $e->getMessage());
      55      exit(mnet_server_fault($e->getCode(), $e->getMessage(), $e->a));
      56  }
      57  
      58  mnet_debug('XMLRPC Payload', 2);
      59  mnet_debug($xmlrpcrequest, 2);
      60  
      61  if($remoteclient->pushkey == true) {
      62      // The peer used one of our older public keys, we will return a
      63      // signed/encrypted error message containing our new public key
      64      // Sign message with our old key, and encrypt to the peer's private key.
      65      mnet_debug('sending back new key');
      66      exit(mnet_server_fault_xml(7025, $mnet->public_key, $remoteclient->useprivatekey));
      67  }
      68  // Have a peek at what the request would be if we were to process it
      69  $params = xmlrpc_decode_request($xmlrpcrequest, $method);
      70  mnet_debug("incoming mnet request $method");
      71  
      72  // One of three conditions need to be met before we continue processing this request:
      73  // 1. Request is properly encrypted and signed
      74  // 2. Request is for a keyswap (we don't mind enencrypted or unsigned requests for a public key)
      75  // 3. Request is properly signed and we're happy with it being unencrypted
      76  if ((($remoteclient->request_was_encrypted == true) && ($remoteclient->signatureok == true))
      77      || (($method == 'system.keyswap') || ($method == 'system/keyswap'))
      78      || (($remoteclient->signatureok == true) && ($remoteclient->plaintext_is_ok() == true))) {
      79      try {
      80          // main dispatch call.  will echo the response directly
      81          mnet_server_dispatch($xmlrpcrequest);
      82          mnet_debug('exiting cleanly');
      83          exit;
      84      } catch (Exception $e) {
      85          mnet_debug('dispatch exception thrown: ' . $e->getMessage());
      86          exit(mnet_server_fault($e->getCode(), $e->getMessage(), $e->a));
      87      }
      88  }
      89  // if we get to here, something is wrong
      90  // so detect a few common cases and send appropriate errors
      91  if (($remoteclient->request_was_encrypted == false) && ($remoteclient->plaintext_is_ok() == false)) {
      92      mnet_debug('non encrypted request');
      93      exit(mnet_server_fault(7021, get_string('forbidden-transport', 'mnet')));
      94  }
      95  
      96  if ($remoteclient->request_was_signed == false) {
      97      // Request was not signed
      98      mnet_debug('non signed request');
      99      exit(mnet_server_fault(711, get_string('verifysignature-error', 'mnet')));
     100  }
     101  
     102  if ($remoteclient->signatureok == false) {
     103      // We were unable to verify the signature
     104      mnet_debug('non verified signature');
     105      exit(mnet_server_fault(710, get_string('verifysignature-invalid', 'mnet')));
     106  }
     107  mnet_debug('unknown error');
     108  exit(mnet_server_fault(7000, get_string('unknownerror', 'mnet')));
    

    Search This Site: