public function bootstrap($wwwroot, $pubkey, $appname = 'moodle', $institution = null) { $wwwroot = dropslash($wwwroot); if (!$this->findByWwwroot($wwwroot)) { $hostname = get_hostname_from_uri($wwwroot); // Get the IP address for that host - if this fails, it will // return the hostname string $ipaddress = gethostbyname($hostname); // Couldn't find the IP address? if ($ipaddress === $hostname && !preg_match('/^\\d+\\.\\d+\\.\\d+.\\d+$/', $hostname)) { throw new ParamOutOfRangeException('Could not find IP address for host: ' . addslashes($hostname)); return false; } // Default the name to the wwwroot $this->name = $wwwroot; // Get a page from the remote host, and check its title. $homepage = file_get_contents($wwwroot); if (!empty($homepage) && ($count = preg_match("@<title>(.*)</title>@siU", $homepage, $matches))) { $this->name = $matches[1]; } $exists = get_record('application', 'name', $appname); if (empty($exists)) { throw new ParamOutOfRangeException('Application ' . addslashes($appname) . ' does not exist.'); } $this->appname = $appname; $this->application = Application::findByName($this->appname); $this->wwwroot = $wwwroot; $this->ipaddress = $ipaddress; require_once get_config('libroot') . 'institution.php'; if (null == $institution) { $institution = new Institution(); $institution->name = preg_replace('/[^a-zA-Z]/', '', $this->name); // Check that the institution name has not already been taken. // If it has, we change it until we find a name that works $existinginstitutionnames = get_column('institution', 'name'); if (in_array($institution->name, $existinginstitutionnames)) { $success = false; foreach (range('a', 'z') as $character) { $testname = $institution->name . $character; if (!in_array($testname, $existinginstitutionnames)) { $success = true; $institution->name = $testname; break; } } if (!$success) { // We couldn't find a unique name. Noes! throw new RemoteServerException('Could not create a unique institution name'); } } $institution->displayname = $this->name; $institution->commit(); $this->institution = $institution->name; } else { $this->institution = $institution; } if (empty($pubkey)) { try { $somekey = get_public_key($this->wwwroot, $this->appname); $this->publickey = new PublicKey($somekey, $this->wwwroot); } catch (XmlrpcClientException $e) { $errcode = $e->getCode(); if ($errcode == 404) { throw new RemoteServerException('404: Incorrect WWWRoot or Application: file not found.'); } elseif ($errcode == 704) { throw new RemoteServerException('Networking is disabled on the host at ' . $this->wwwroot . '.'); } else { throw new RemoteServerException('Error retrieving public key, failed with error code ' . $errcode . ': ' . $e->getMessage()); } } catch (Exception $e) { throw new RemoteServerException('Error retrieving public key: ' . $e->getMessage()); } } else { $this->publickey = new PublicKey($pubkey, $this->wwwroot); } $this->lastconnecttime = 0; $this->initialized = self::INITIALIZED; $this->changed = true; if (false == $this->publickey->expires) { $this->publickey == null; return false; } } return true; }
/** * Generate public/private keys and store in the config table * * Use the distinguished name provided to create a CSR, and then sign that CSR * with the same credentials. Store the keypair you create in the config table. * If a distinguished name is not provided, create one using the fullname of * 'the course with ID 1' as your organization name, and your hostname (as * detailed in $CFG->wwwroot). * * @param array $dn The distinguished name of the server * @return string The signature over that text */ private function generate_keypair() { $host = get_hostname_from_uri(get_config('wwwroot')); $organization = get_config('sitename'); $email = get_config('noreplyaddress'); $country = get_config('country'); $province = get_config('province'); $locality = get_config('locality'); //TODO: Create additional fields on site setup and read those from // config. Then remove the next 3 linez if (empty($country)) { $country = 'NZ'; } if (empty($province)) { $province = 'Wellington'; } if (empty($locality)) { $locality = 'Te Aro'; } $dn = array("countryName" => $country, "stateOrProvinceName" => $province, "localityName" => $locality, "organizationName" => $organization, "organizationalUnitName" => 'Mahara', "commonName" => get_config('wwwroot'), "emailAddress" => $email); // ensure we remove trailing slashes $dn["commonName"] = preg_replace(':/$:', '', $dn["commonName"]); $config = array(); $opensslcnf = get_config('opensslcnf'); if ($opensslcnf) { $config['config'] = $opensslcnf; } else { $config = null; } if (!($new_key = openssl_pkey_new($config))) { throw new ConfigException(get_string('errorcouldnotgeneratenewsslkey', 'auth')); } if (!($csr_rsc = openssl_csr_new($dn, $new_key, $config))) { // This behaviour has been observed once before, on an ubuntu hardy box. // The php5-openssl package was installed but somehow openssl // wasn't. throw new ConfigException(get_string('errorcouldnotgeneratenewsslkey', 'auth')); } $selfSignedCert = openssl_csr_sign($csr_rsc, null, $new_key, 365, $config); unset($csr_rsc); // Free up the resource // We export our self-signed certificate to a string. openssl_x509_export($selfSignedCert, $this->keypair['certificate']); openssl_x509_free($selfSignedCert); // Export your public/private key pair as a PEM encoded string. You // can protect it with an optional passphrase if you wish. $export = openssl_pkey_export($new_key, $this->keypair['keypair_PEM'], null, $config); openssl_pkey_free($new_key); unset($new_key); // Free up the resource // Calculate fingerprints $this->calculate_fingerprints(); return $this; }
// Do we respond with verbose error messages? $networkingdebug = get_config('enablenetworkingdebug'); // If networking is off, return a '403 Forbidden' response $networkenabled = get_config('enablenetworking'); $protocol = strtoupper($_SERVER['SERVER_PROTOCOL']); if ($protocol != 'HTTP/1.1') { $protocol = 'HTTP/1.0'; } if (empty($networkenabled)) { if ($networkingdebug) { throw new XmlrpcServerException('Networking is disabled.', 6012); } header($protocol . ' 403 Forbidden'); exit; } if (get_hostname_from_uri($_SERVER['HTTP_HOST']) != get_hostname_from_uri(get_config('wwwroot'))) { throw new XmlrpcServerException('Networking is not available at this address. You can access this service at ' . get_config('wwwroot') . 'api/xmlrpc/server.php', 6013); } // Content type for output is never html: header('Content-type: text/xml; charset=utf-8'); ini_set('display_errors', 0); if (!empty($errors)) { throw new XmlrpcServerException('Initialization failed. Non-recoverable error.', 6000); } // PHP 5.2.2: $HTTP_RAW_POST_DATA not populated bug: // http://bugs.php.net/bug.php?id=41293 if (empty($HTTP_RAW_POST_DATA)) { $HTTP_RAW_POST_DATA = file_get_contents('php://input'); } // A singleton provides our site's SSL info $openssl = OpenSslRepo::singleton();