Esempio n. 1
0
 function bootstrap($wwwroot, $pubkey = null, $application)
 {
     if (substr($wwwroot, -1, 1) == '/') {
         $wwwroot = substr($wwwroot, 0, -1);
     }
     if (!$this->set_wwwroot($wwwroot)) {
         $hostname = mnet_get_hostname_from_uri($wwwroot);
         // Get the IP address for that host - if this fails, it will
         // return the hostname string
         $ip_address = gethostbyname($hostname);
         // Couldn't find the IP address?
         if ($ip_address === $hostname && !preg_match('/^\\d+\\.\\d+\\.\\d+.\\d+$/', $hostname)) {
             $this->error[] = array('code' => 2, 'text' => get_string("noaddressforhost", 'mnet'));
             return false;
         }
         $this->name = stripslashes($wwwroot);
         $this->updateparams->name = $wwwroot;
         // TODO: In reality, this will be prohibitively slow... need another
         // default - maybe blank string
         $homepage = file_get_contents($wwwroot);
         if (!empty($homepage)) {
             $count = preg_match("@<title>(.*)</title>@siU", $homepage, $matches);
             if ($count > 0) {
                 $this->name = $matches[1];
                 $this->updateparams->name = addslashes($matches[1]);
             }
         }
         $this->wwwroot = stripslashes($wwwroot);
         $this->updateparams->wwwroot = $wwwroot;
         $this->ip_address = $ip_address;
         $this->updateparams->ip_address = $ip_address;
         $this->deleted = 0;
         $this->updateparams->deleted = 0;
         $this->application = get_record('mnet_application', 'name', $application);
         if (empty($this->application)) {
             $this->application = get_record('mnet_application', 'name', 'moodle');
         }
         $this->applicationid = $this->application->id;
         $this->updateparams->applicationid = $this->application->id;
         if (empty($pubkey)) {
             $pubkeytemp = clean_param(mnet_get_public_key($this->wwwroot, $this->application), PARAM_PEM);
         } else {
             $pubkeytemp = clean_param($pubkey, PARAM_PEM);
         }
         $this->public_key_expires = $this->check_common_name($pubkeytemp);
         if ($this->public_key_expires == false) {
             return false;
         }
         $this->updateparams->public_key_expires = $this->public_key_expires;
         $this->updateparams->public_key = $pubkeytemp;
         $this->public_key = $pubkeytemp;
         $this->last_connect_time = 0;
         $this->updateparams->last_connect_time = 0;
         $this->last_log_id = 0;
         $this->updateparams->last_log_id = 0;
     }
     return true;
 }
Esempio n. 2
0
 function bootstrap($wwwroot, $pubkey = null, $application)
 {
     global $DB;
     if (substr($wwwroot, -1, 1) == '/') {
         $wwwroot = substr($wwwroot, 0, -1);
     }
     // If a peer record already exists for this address,
     // load that info and return
     if ($this->set_wwwroot($wwwroot)) {
         return true;
     }
     $hostname = mnet_get_hostname_from_uri($wwwroot);
     // Get the IP address for that host - if this fails, it will return the hostname string
     $ip_address = gethostbyname($hostname);
     // Couldn't find the IP address?
     if ($ip_address === $hostname && !preg_match('/^\\d+\\.\\d+\\.\\d+.\\d+$/', $hostname)) {
         throw new moodle_exception('noaddressforhost', 'mnet', '', $hostname);
     }
     $this->name = $wwwroot;
     // TODO: In reality, this will be prohibitively slow... need another
     // default - maybe blank string
     $homepage = download_file_content($wwwroot);
     if (!empty($homepage)) {
         $count = preg_match("@<title>(.*)</title>@siU", $homepage, $matches);
         if ($count > 0) {
             $this->name = $matches[1];
         }
     }
     $this->wwwroot = $wwwroot;
     $this->ip_address = $ip_address;
     $this->deleted = 0;
     $this->application = $DB->get_record('mnet_application', array('name' => $application));
     if (empty($this->application)) {
         $this->application = $DB->get_record('mnet_application', array('name' => 'moodle'));
     }
     $this->applicationid = $this->application->id;
     if (empty($pubkey)) {
         $this->public_key = clean_param(mnet_get_public_key($this->wwwroot, $this->application), PARAM_PEM);
     } else {
         $this->public_key = clean_param($pubkey, PARAM_PEM);
     }
     $this->public_key_expires = $this->check_common_name($this->public_key);
     $this->last_connect_time = 0;
     $this->last_log_id = 0;
     if ($this->public_key_expires == false) {
         $this->public_key == '';
         return false;
     }
     $this->bootstrapped = true;
 }
Esempio n. 3
0
    exit;
} else {
    if ($simpleform->is_submitted()) {
        // validation failed
        $noreviewform = true;
    }
}
// editing a host - load up the review form
if (!empty($hostid)) {
    // TODO print a nice little heading
    $mnet_peer->set_id($hostid);
    echo $OUTPUT->header();
    $currenttab = 'mnetdetails';
    require_once $CFG->dirroot . '/admin/mnet/tabs.php';
    if ($hostid != $CFG->mnet_all_hosts_id) {
        $mnet_peer->currentkey = mnet_get_public_key($mnet_peer->wwwroot, $mnet_peer->application);
        if ($mnet_peer->currentkey == $mnet_peer->public_key) {
            unset($mnet_peer->currentkey);
        } else {
            error_log($mnet_peer->currentkey);
            error_log($mnet_peer->public_key);
            error_log(md5($mnet_peer->currentkey));
            error_log(md5($mnet_peer->public_key));
        }
        $credentials = $mnet_peer->check_credentials($mnet_peer->public_key);
        $reviewform = new mnet_review_host_form(null, array('peer' => $mnet_peer));
        // the second step (also the edit host form)
        $mnet_peer->oldpublickey = $mnet_peer->public_key;
        // set this so we can confirm on form post without having to recreate the mnet_peer object
        $reviewform->set_data((object) $mnet_peer);
        echo $OUTPUT->box_start();
 // renew local key
 $mnet->replace_keys();
 // send new key using key exchange transportation
 // make a key and exchange it with all known and active peers
 $mnet_peers = $DB->get_records('mnet_host', array('deleted' => 0));
 if ($mnet_peers) {
     foreach ($mnet_peers as $peer) {
         if ($peer->id == $CFG->mnet_all_hosts_id || $peer->id == $CFG->mnet_localhost_id) {
             continue;
         }
         $application = $DB->get_record('mnet_application', array('id' => $peer->applicationid));
         $mnet_peer = new mnet_peer();
         $mnet_peer->set_wwwroot($peer->wwwroot);
         // get the sessions for each vmoodle that have same ID Number
         // we use a force parameter to force fetching the key remotely anyway
         $currentkey = mnet_get_public_key($mnet_peer->wwwroot, $application, 1);
         if ($currentkey) {
             $mnet_peer->public_key = clean_param($currentkey, PARAM_PEM);
             $mnet_peer->updateparams = new StdClass();
             $mnet_peer->updateparams->public_key = clean_param($currentkey, PARAM_PEM);
             $mnet_peer->public_key_expires = $mnet_peer->check_common_name($currentkey);
             $mnet_peer->updateparams->public_key_expires = $mnet_peer->check_common_name($currentkey);
             $mnet_peer->commit();
             mtrace('My key renewed at ' . $peer->wwwroot . ' till ' . userdate($mnet_peer->public_key_expires));
             $trace .= userdate(time()) . ' KEY RENEW from ' . $CFG->wwwroot . ' to ' . $peer->wwwroot . " suceeded\n";
         } else {
             mtrace('Failed renewing key with ' . $peer->wwwroot . "\n");
             $trace .= userdate(time()) . ' KEY RENEW from ' . $CFG->wwwroot . ' to ' . $peer->wwwroot . " failed\n";
         }
     }
 }
Esempio n. 5
0
function mnet_server_strip_signature($plaintextmessage) {
    $remoteclient = get_mnet_remote_client();
    $sig_parser = new mnet_encxml_parser();
    $sig_parser->parse($plaintextmessage);

    if ($sig_parser->signature == '') {
        return $plaintextmessage;
    }

    // Record that the request was signed in some way
    $remoteclient->was_signed();

    // Load any information we have about this mnet peer
    $remoteclient->set_wwwroot($sig_parser->remote_wwwroot);

    $payload = base64_decode($sig_parser->data_object);
    $signature = base64_decode($sig_parser->signature);
    $certificate = $remoteclient->public_key;

    // If we don't have any certificate for the host, don't try to check the signature
    // Just return the parsed request
    if ($certificate == false) {
        return $payload;
    }

    // Does the signature match the data and the public cert?
    $signature_verified = openssl_verify($payload, $signature, $certificate);
    if ($signature_verified == 0) {
        // $signature was not generated for $payload using $certificate
        // Get the key the remote peer is currently publishing:
        $currkey = mnet_get_public_key($remoteclient->wwwroot, $remoteclient->application);
        // If the key the remote peer is currently publishing is different to $certificate
        if($currkey != $certificate) {
            // if pushkey is already set, it means the request was encrypted to an old key
            // in mnet_server_strip_encryption.
            // if we call refresh_key() here before pushing out our new key,
            // and the other site ALSO has a new key,
            // we'll get into an infinite keyswap loop
            // so push just bail here, and push out the new key.
            // the next request will get through to refresh_key
            if ($remoteclient->pushkey) {
                return false;
            }
            // Try and get the server's new key through trusted means
            $remoteclient->refresh_key();
            // If we did manage to re-key, try to verify the signature again using the new public key.
            $certificate = $remoteclient->public_key;
            $signature_verified = openssl_verify($payload, $signature, $certificate);
        }
    }

    if ($signature_verified == 1) {
        $remoteclient->signature_verified();
        $remoteclient->touch();
    }

    $sig_parser->free_resource();

    return $payload;
}
Esempio n. 6
0
/**
 * Strip the encryption (XML-ENC) and signature (XML-SIG) wrappers and return the XML-RPC payload
 *
 * IF COMMUNICATION TAKES PLACE OVER UNENCRYPTED HTTP:
 * The payload will have been encrypted with a symmetric key. This key will
 * itself have been encrypted using your public key. The key is decrypted using
 * your private key, and then used to decrypt the XML payload.
 *
 * IF COMMUNICATION TAKES PLACE OVER UNENCRYPTED HTTP *OR* ENCRYPTED HTTPS:
 * In either case, there will be an XML wrapper which contains your XML-RPC doc
 * as an object element, a signature for that doc, and various standards-
 * compliant info to aid in verifying the signature.
 *
 * This function parses the encryption wrapper, decrypts the contents, parses
 * the signature wrapper, and if the signature matches the payload, it returns
 * the payload, which should be an XML-RPC request.
 * If there is an error, or the signatures don't match, it echoes an XML-RPC
 * error and exits.
 *
 * See the W3C's {@link http://www.w3.org/TR/xmlenc-core/ XML Encryption Syntax and Processing}
 * and {@link http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/ XML-Signature Syntax and Processing}
 * guidelines for more detail on the XML.
 *
 * -----XML-Envelope---------------------------------
 * |                                                |
 * |    Encrypted-Symmetric-key----------------     |
 * |    |_____________________________________|     |
 * |                                                |
 * |    Encrypted data-------------------------     |
 * |    |                                     |     |
 * |    |  -XML-Envelope------------------    |     |
 * |    |  |                             |    |     |
 * |    |  |  --Signature-------------   |    |     |
 * |    |  |  |______________________|   |    |     |
 * |    |  |                             |    |     |
 * |    |  |  --Signed-Payload--------   |    |     |
 * |    |  |  |                      |   |    |     |
 * |    |  |  |   XML-RPC Request    |   |    |     |
 * |    |  |  |______________________|   |    |     |
 * |    |  |                             |    |     |
 * |    |  |_____________________________|    |     |
 * |    |_____________________________________|     |
 * |                                                |
 * |________________________________________________|
 *
 * @uses $db
 * @param   string  $HTTP_RAW_POST_DATA   The XML that the client sent
 * @return  string                        The XMLRPC payload.
 */
function mnet_server_strip_wrappers($HTTP_RAW_POST_DATA)
{
    global $MNET, $MNET_REMOTE_CLIENT;
    if (isset($_SERVER)) {
        $crypt_parser = new mnet_encxml_parser();
        $crypt_parser->parse($HTTP_RAW_POST_DATA);
        // Make sure we know who we're talking to
        $host_record_exists = $MNET_REMOTE_CLIENT->set_wwwroot($crypt_parser->remote_wwwroot);
        if (false == $host_record_exists) {
            exit(mnet_server_fault(7020, 'wrong-wwwroot', $crypt_parser->remote_wwwroot));
        }
        if ($crypt_parser->payload_encrypted) {
            $key = array_pop($crypt_parser->cipher);
            // This key is Symmetric
            $data = array_pop($crypt_parser->cipher);
            $crypt_parser->free_resource();
            $payload = '';
            // Initialize payload var
            $push_current_key = false;
            // True if we need to push a fresh key to the peer
            //                                          &$payload
            $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $MNET->get_private_key());
            if (!$isOpen) {
                // Decryption failed... let's try our archived keys
                $openssl_history = get_config('mnet', 'openssl_history');
                if (empty($openssl_history)) {
                    $openssl_history = array();
                    set_config('openssl_history', serialize($openssl_history), 'mnet');
                } else {
                    $openssl_history = unserialize($openssl_history);
                }
                foreach ($openssl_history as $keyset) {
                    $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']);
                    $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $keyresource);
                    if ($isOpen) {
                        // It's an older code, sir, but it checks out
                        $push_current_key = true;
                        break;
                    }
                }
            }
            if (!$isOpen) {
                exit(mnet_server_fault(7023, 'encryption-invalid'));
            }
            if (strpos(substr($payload, 0, 100), '<signedMessage>')) {
                $MNET_REMOTE_CLIENT->was_signed();
                $sig_parser = new mnet_encxml_parser();
                $sig_parser->parse($payload);
            } else {
                exit(mnet_server_fault(7022, 'verifysignature-error'));
            }
        } else {
            exit(mnet_server_fault(7024, 'payload-not-encrypted'));
        }
        unset($payload);
        // if the peer used one of our public keys that have expired, we will
        // return a signed/encrypted error message with our new public key
        if ($push_current_key) {
            // NOTE: Here, we use the 'mnet_server_fault_xml' to avoid
            // get_string being called on our public_key
            exit(mnet_server_fault_xml(7025, $MNET->public_key, $keyresource));
        }
        /**
         * Get the certificate (i.e. public key) from the remote server.
         */
        $certificate = $MNET_REMOTE_CLIENT->public_key;
        if ($certificate == false) {
            exit(mnet_server_fault(709, 'nosuchpublickey'));
        }
        $payload = base64_decode($sig_parser->data_object);
        // Does the signature match the data and the public cert?
        $signature_verified = openssl_verify($payload, base64_decode($sig_parser->signature), $certificate);
        if ($signature_verified == 0) {
            // $signature was not generated for $payload using $certificate
            // Get the key the remote peer is currently publishing:
            $currkey = mnet_get_public_key($MNET_REMOTE_CLIENT->wwwroot, $MNET_REMOTE_CLIENT->application->xmlrpc_server_url);
            // If the key the remote peer is currently publishing is different to $certificate
            if ($currkey != $certificate) {
                // If we can't get the server's new key through trusted means, exit.
                if (!$MNET_REMOTE_CLIENT->refresh_key()) {
                    exit(mnet_server_fault(7026, 'verifysignature-invalid'));
                }
                // If we did manage to re-key, try to verify the signature again against the new public key.
                $certificate = $MNET_REMOTE_CLIENT->public_key;
                $signature_verified = openssl_verify($payload, base64_decode($sig_parser->signature), $certificate);
            }
        }
        if ($signature_verified == 1) {
            $MNET_REMOTE_CLIENT->touch();
        } elseif ($signature_verified == 0) {
            exit(mnet_server_fault(710, 'verifysignature-invalid'));
        } else {
            exit(mnet_server_fault(711, 'verifysignature-error'));
        }
        $sig_parser->free_resource();
        return $payload;
    } else {
        exit(mnet_server_fault(712, "phperror"));
    }
}
 function bootstrap($wwwroot, $pubkey = null, $application, $force = false, $localname = '')
 {
     global $DB;
     if (substr($wwwroot, -1, 1) == '/') {
         $wwwroot = substr($wwwroot, 0, -1);
     }
     if (!$this->set_wwwroot($wwwroot)) {
         $hostname = mnet_get_hostname_from_uri($wwwroot);
         // Get the IP address for that host - if this fails, it will
         // return the hostname string
         $ip_address = gethostbyname($hostname);
         // Couldn't find the IP address?
         if ($ip_address === $hostname && !preg_match('/^\\d+\\.\\d+\\.\\d+.\\d+$/', $hostname)) {
             $this->errors[] = 'ErrCode 2 - ' . get_string("noaddressforhost", 'mnet');
             return false;
         }
         if (empty($localname)) {
             $this->name = stripslashes($wwwroot);
             $this->updateparams->name = $wwwroot;
         } else {
             $this->name = $localname;
             $this->updateparams->name = $localname;
         }
         // TODO: In reality, this will be prohibitively slow... need another
         // default - maybe blank string
         $homepage = file_get_contents($wwwroot);
         if (!empty($homepage)) {
             $count = preg_match("@<title>(.*)</title>@siU", $homepage, $matches);
             if ($count > 0) {
                 $this->name = $matches[1];
                 $this->updateparams->name = str_replace("'", "''", $matches[1]);
             }
         } else {
             // debug_trace("Missing remote real name guessing, no other side response");
         }
         // debug_trace("final name : ".$this->name);
         $this->wwwroot = stripslashes($wwwroot);
         $this->updateparams->wwwroot = $wwwroot;
         $this->ip_address = $ip_address;
         $this->updateparams->ip_address = $ip_address;
         $this->deleted = 0;
         $this->updateparams->deleted = 0;
         $this->application = $DB->get_record('mnet_application', array('name' => $application));
         if (empty($this->application)) {
             $this->application = $DB->get_record('mnet_application', array('name' => 'moodle'));
         }
         $this->applicationid = $this->application->id;
         $this->updateparams->applicationid = $this->application->id;
         // start bootstraping as usual through the system command
         $pubkeytemp = clean_param(mnet_get_public_key($this->wwwroot, $this->application), PARAM_PEM);
         if (empty($pubkey)) {
             // This is the key difference : force the exchange using vmoodle RPC keyswap !!
             if (empty($pubkeytemp)) {
                 $pubkeytemp = clean_param(mnet_get_public_key($this->wwwroot, $this->application, $force), PARAM_PEM);
             }
         } else {
             $pubkeytemp = clean_param($pubkey, PARAM_PEM);
         }
         $this->public_key_expires = $this->check_common_name($pubkeytemp);
         if ($this->public_key_expires == false) {
             return false;
         }
         $this->updateparams->public_key_expires = $this->public_key_expires;
         $this->updateparams->public_key = $pubkeytemp;
         $this->public_key = $pubkeytemp;
         $this->last_connect_time = 0;
         $this->updateparams->last_connect_time = 0;
         $this->last_log_id = 0;
         $this->updateparams->last_log_id = 0;
     }
     return true;
 }
Esempio n. 8
0
function mnet_server_strip_signature($plaintextmessage)
{
    global $MNET, $MNET_REMOTE_CLIENT;
    $sig_parser = new mnet_encxml_parser();
    $sig_parser->parse($plaintextmessage);
    if ($sig_parser->signature == '') {
        return $plaintextmessage;
    }
    // Record that the request was signed in some way
    $MNET_REMOTE_CLIENT->was_signed();
    // Load any information we have about this mnet peer
    $MNET_REMOTE_CLIENT->set_wwwroot($sig_parser->remote_wwwroot);
    $payload = base64_decode($sig_parser->data_object);
    $signature = base64_decode($sig_parser->signature);
    $certificate = $MNET_REMOTE_CLIENT->public_key;
    // If we don't have any certificate for the host, don't try to check the signature
    // Just return the parsed request
    if ($certificate == false) {
        return $payload;
    }
    // Does the signature match the data and the public cert?
    $signature_verified = openssl_verify($payload, $signature, $certificate);
    if ($signature_verified == 0) {
        // $signature was not generated for $payload using $certificate
        // Get the key the remote peer is currently publishing:
        $currkey = mnet_get_public_key($MNET_REMOTE_CLIENT->wwwroot, $MNET_REMOTE_CLIENT->application);
        // If the key the remote peer is currently publishing is different to $certificate
        if ($currkey != $certificate) {
            // Try and get the server's new key through trusted means
            $MNET_REMOTE_CLIENT->refresh_key();
            // If we did manage to re-key, try to verify the signature again using the new public key.
            $certificate = $MNET_REMOTE_CLIENT->public_key;
            $signature_verified = openssl_verify($payload, $signature, $certificate);
        }
    }
    if ($signature_verified == 1) {
        $MNET_REMOTE_CLIENT->signature_verified();
        $MNET_REMOTE_CLIENT->touch();
    }
    $sig_parser->free_resource();
    return $payload;
}
Esempio n. 9
0
        }
        if ('input' == $form->step) {
            include './mnet_review.html';
        } elseif ('commit' == $form->step) {
            $bool = $mnet_peer->commit();
            if ($bool) {
                redirect('peers.php?step=update&amp;hostid=' . $mnet_peer->id, get_string('changessaved'));
            } else {
                error('Invalid action parameter.', 'index.php');
            }
        }
    }
} elseif (is_int($hostid)) {
    $mnet_peer = new mnet_peer();
    $mnet_peer->set_id($hostid);
    $currentkey = mnet_get_public_key($mnet_peer->wwwroot);
    if ($currentkey == $mnet_peer->public_key) {
        unset($currentkey);
    }
    $form = new stdClass();
    if ($hostid != $CFG->mnet_all_hosts_id) {
        include './mnet_review.html';
    } else {
        include './mnet_review_allhosts.html';
    }
} else {
    $hosts = get_records_select('mnet_host', " id != '{$CFG->mnet_localhost_id}' AND deleted = '0' ", 'wwwroot ASC');
    if (empty($hosts)) {
        $hosts = array();
    }
    include './peers.html';