/** * For XML-RPC - we want to check for enc / sigs * * @return $xml */ protected function modify_payload() { global $HTTP_RAW_POST_DATA; $xml = null; // check for encryption and signatures if ($this->authmethod == WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN) { // we need the token so that we can find the key if (!($dbtoken = get_record('external_tokens', 'token', $this->token, 'tokentype', EXTERNAL_TOKEN_PERMANENT))) { // log failed login attempts throw new WebserviceAccessException(get_string('invalidtoken', 'auth.webservice')); } // is WS-Security active ? if ($dbtoken->wssigenc) { $this->publickey = $dbtoken->publickey; } } else { if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { // get the user $user = get_record('usr', 'username', $this->username); if (empty($user)) { throw new WebserviceAccessException(get_string('wrongusernamepassword', 'auth.webservice')); } // get the institution from the external user $ext_user = get_record('external_services_users', 'userid', $user->id); if (empty($ext_user)) { throw new WebserviceAccessException(get_string('wrongusernamepassword', 'auth.webservice')); } // is WS-Security active ? if ($ext_user->wssigenc) { $this->publickey = $ext_user->publickey; } } } // only both if we can find a public key if (!empty($this->publickey)) { // A singleton provides our site's SSL info require_once get_config('docroot') . 'api/xmlrpc/lib.php'; $HTTP_RAW_POST_DATA = file_get_contents('php://input'); $openssl = OpenSslRepo::singleton(); $payload = $HTTP_RAW_POST_DATA; $this->payload_encrypted = false; $this->payload_signed = false; try { $xml = new SimpleXMLElement($payload); } catch (Exception $e) { throw new XmlrpcServerException('Payload is not a valid XML document', 6001); } // Cascading switch. Kinda. try { if ($xml->getName() == 'encryptedMessage') { $this->payload_encrypted = true; $payload = xmlenc_envelope_strip($xml); } if ($xml->getName() == 'signedMessage') { $this->payload_signed = true; $payload = xmldsig_envelope_strip($xml); } $xml = $payload; } catch (CryptException $e) { if ($e->getCode() == 7025) { // The key they used to contact us is old, respond with the new key correctly // This sucks. Error handling of our mnet code needs to improve ob_start(); xmlrpc_error($e->getMessage(), $e->getCode()); $response = ob_get_contents(); ob_end_clean(); // Sign and encrypt our response, even though we don't know if the // request was signed and encrypted $response = xmldsig_envelope($response); $response = xmlenc_envelope($response, $this->publickey); $xml = $response; } } } // if XML has been grabbed already then it must be turned into a request object if ($xml) { $request = new Zend_XmlRpc_Request(); $request->loadXML($xml); $xml = $request; } return $xml; }