/** * Get WSDL contents */ function rcommon_get_wsdl($urlwdsl, $timeout = 20) { global $CFG; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $urlwdsl); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout); if (!is_proxybypass($urlwdsl)) { if (!empty($CFG->proxytype) && $CFG->proxytype == 'HTTP' && !empty($CFG->proxyhost)) { curl_setopt($curl, CURLOPT_PROXY, $CFG->proxyhost); if (!empty($CFG->proxyport)) { curl_setopt($curl, CURLOPT_PROXYPORT, $CFG->proxyport); } if (!empty($CFG->proxyuser)) { curl_setopt($curl, CURLOPT_PROXYUSERPWD, $CFG->proxyuser . ':' . $CFG->proxypassword); } } } $contents = curl_exec($curl); curl_close($curl); return $contents; }
/** * Constructor * * @param string $serverurl a Moodle URL * @param string $token the token used to do the web service call */ public function __construct($serverurl, $token) { global $CFG; $this->serverurl = $serverurl; $serverurl = $serverurl . '?wstoken=' . $token; parent::__construct($serverurl); if (!empty($CFG->proxyhost) && !is_proxybypass($serverurl)) { $config = array('adapter' => 'Zend_Http_Client_Adapter_Proxy', 'proxy_host' => $CFG->proxyhost, 'proxy_user' => !empty($CFG->proxyuser) ? $CFG->proxyuser : null, 'proxy_pass' => !empty($CFG->proxypassword) ? $CFG->proxypassword : null); if (!empty($CFG->proxyport)) { $config['proxy_port'] = $CFG->proxyport; } $this->getHttpClient()->setConfig($config); } }
/** * Prepares a renderable widget to execute installation of an available update. * * @param available_update_info $info component version to deploy * @param moodle_url $returnurl URL to return after the installation execution * @return renderable */ public function make_execution_widget(available_update_info $info, moodle_url $returnurl = null) { global $CFG; if (!$this->initialized()) { throw new coding_exception('Illegal method call - deployer not initialized.'); } $pluginrootpaths = get_plugin_types(true); list($plugintype, $pluginname) = normalize_component($info->component); if (empty($pluginrootpaths[$plugintype])) { throw new coding_exception('Unknown plugin type root location', $plugintype); } list($passfile, $password) = $this->prepare_authorization(); if (is_null($returnurl)) { $returnurl = new moodle_url('/admin'); } else { $returnurl = $returnurl; } $params = array('upgrade' => true, 'type' => $plugintype, 'name' => $pluginname, 'typeroot' => $pluginrootpaths[$plugintype], 'package' => $info->download, 'md5' => $info->downloadmd5, 'dataroot' => $CFG->dataroot, 'dirroot' => $CFG->dirroot, 'passfile' => $passfile, 'password' => $password, 'returnurl' => $returnurl->out(false)); if (!empty($CFG->proxyhost)) { // MDL-36973 - Beware - we should call just !is_proxybypass() here. But currently, our // cURL wrapper class does not do it. So, to have consistent behaviour, we pass proxy // setting regardless the $CFG->proxybypass setting. Once the {@link curl} class is // fixed, the condition should be amended. if (true or !is_proxybypass($info->download)) { if (empty($CFG->proxyport)) { $params['proxy'] = $CFG->proxyhost; } else { $params['proxy'] = $CFG->proxyhost . ':' . $CFG->proxyport; } if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) { $params['proxyuserpwd'] = $CFG->proxyuser . ':' . $CFG->proxypassword; } if (!empty($CFG->proxytype)) { $params['proxytype'] = $CFG->proxytype; } } } $widget = new single_button(new moodle_url('/mdeploy.php', $params), get_string('updateavailableinstall', 'core_admin'), 'post'); return $widget; }
/** * Set options for individual curl instance * * @param resource $curl A curl handle * @param array $options * @return resource The curl handle */ private function apply_opt($curl, $options) { // Clean up $this->cleanopt(); // set cookie if (!empty($this->cookie) || !empty($options['cookie'])) { $this->setopt(array('cookiejar' => $this->cookie, 'cookiefile' => $this->cookie)); } // Bypass proxy if required. if ($this->proxy === null) { if (!empty($this->options['CURLOPT_URL']) and is_proxybypass($this->options['CURLOPT_URL'])) { $proxy = false; } else { $proxy = true; } } else { $proxy = (bool) $this->proxy; } // Set proxy. if ($proxy) { $options['CURLOPT_PROXY'] = $this->proxy_host; } else { unset($this->options['CURLOPT_PROXY']); } $this->setopt($options); // Reset before set options. curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, 'formatHeader')); // Setting the User-Agent based on options provided. $useragent = ''; if (!empty($options['CURLOPT_USERAGENT'])) { $useragent = $options['CURLOPT_USERAGENT']; } else { if (!empty($this->options['CURLOPT_USERAGENT'])) { $useragent = $this->options['CURLOPT_USERAGENT']; } else { $useragent = 'MoodleBot/1.0'; } } // Set headers. if (empty($this->header)) { $this->setHeader(array('User-Agent: ' . $useragent, 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Connection: keep-alive')); } else { if (!in_array('User-Agent: ' . $useragent, $this->header)) { // Remove old User-Agent if one existed. // We have to partial search since we don't know what the original User-Agent is. if ($match = preg_grep('/User-Agent.*/', $this->header)) { $key = array_keys($match)[0]; unset($this->header[$key]); } $this->setHeader(array('User-Agent: ' . $useragent)); } } curl_setopt($curl, CURLOPT_HTTPHEADER, $this->header); if ($this->debug) { echo '<h1>Options</h1>'; var_dump($this->options); echo '<h1>Header</h1>'; var_dump($this->header); } // Do not allow infinite redirects. if (!isset($this->options['CURLOPT_MAXREDIRS'])) { $this->options['CURLOPT_MAXREDIRS'] = 0; } else { if ($this->options['CURLOPT_MAXREDIRS'] > 100) { $this->options['CURLOPT_MAXREDIRS'] = 100; } else { $this->options['CURLOPT_MAXREDIRS'] = (int) $this->options['CURLOPT_MAXREDIRS']; } } // Make sure we always know if redirects expected. if (!isset($this->options['CURLOPT_FOLLOWLOCATION'])) { $this->options['CURLOPT_FOLLOWLOCATION'] = 0; } // Limit the protocols to HTTP and HTTPS. if (defined('CURLOPT_PROTOCOLS')) { $this->options['CURLOPT_PROTOCOLS'] = CURLPROTO_HTTP | CURLPROTO_HTTPS; $this->options['CURLOPT_REDIR_PROTOCOLS'] = CURLPROTO_HTTP | CURLPROTO_HTTPS; } // Set options. foreach ($this->options as $name => $val) { if ($name === 'CURLOPT_FOLLOWLOCATION' and $this->emulateredirects) { // The redirects are emulated elsewhere. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 0); continue; } $name = constant($name); curl_setopt($curl, $name, $val); } return $curl; }
/** * Fetches content of file from Internet (using proxy if defined). Uses cURL extension if present. * Due to security concerns only downloads from http(s) sources are supported. * * @param string $url file url starting with http(s):// * @param array $headers http headers, null if none. If set, should be an * associative array of header name => value pairs. * @param array $postdata array means use POST request with given parameters * @param bool $fullresponse return headers, responses, etc in a similar way snoopy does * (if false, just returns content) * @param int $timeout timeout for complete download process including all file transfer * (default 5 minutes) * @param int $connecttimeout timeout for connection to server; this is the timeout that * usually happens if the remote server is completely down (default 20 seconds); * may not work when using proxy * @param bool $skipcertverify If true, the peer's SSL certificate will not be checked. * Only use this when already in a trusted location. * @param string $tofile store the downloaded content to file instead of returning it. * @param bool $calctimeout false by default, true enables an extra head request to try and determine * filesize and appropriately larger timeout based on $CFG->curltimeoutkbitrate * @return mixed false if request failed or content of the file as string if ok. True if file downloaded into $tofile successfully. */ function download_file_content($url, $headers = null, $postdata = null, $fullresponse = false, $timeout = 300, $connecttimeout = 20, $skipcertverify = false, $tofile = NULL, $calctimeout = false) { global $CFG; // some extra security $newlines = array("\r", "\n"); if (is_array($headers)) { foreach ($headers as $key => $value) { $headers[$key] = str_replace($newlines, '', $value); } } $url = str_replace($newlines, '', $url); if (!preg_match('|^https?://|i', $url)) { if ($fullresponse) { $response = new stdClass(); $response->status = 0; $response->headers = array(); $response->response_code = 'Invalid protocol specified in url'; $response->results = ''; $response->error = 'Invalid protocol specified in url'; return $response; } else { return false; } } // check if proxy (if used) should be bypassed for this url $proxybypass = is_proxybypass($url); if (!($ch = curl_init($url))) { debugging('Can not init curl.'); return false; } // set extra headers if (is_array($headers)) { $headers2 = array(); foreach ($headers as $key => $value) { $headers2[] = "{$key}: {$value}"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headers2); } if ($skipcertverify) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); } // use POST if requested if (is_array($postdata)) { $postdata = format_postdata_for_curlcall($postdata); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connecttimeout); if (!ini_get('open_basedir') and !ini_get('safe_mode')) { // TODO: add version test for '7.10.5' curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); } if (!empty($CFG->proxyhost) and !$proxybypass) { // SOCKS supported in PHP5 only if (!empty($CFG->proxytype) and $CFG->proxytype == 'SOCKS5') { if (defined('CURLPROXY_SOCKS5')) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } else { curl_close($ch); if ($fullresponse) { $response = new stdClass(); $response->status = '0'; $response->headers = array(); $response->response_code = 'SOCKS5 proxy is not supported in PHP4'; $response->results = ''; $response->error = 'SOCKS5 proxy is not supported in PHP4'; return $response; } else { debugging("SOCKS5 proxy is not supported in PHP4.", DEBUG_ALL); return false; } } } curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false); if (empty($CFG->proxyport)) { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost); } else { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost . ':' . $CFG->proxyport); } if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $CFG->proxyuser . ':' . $CFG->proxypassword); if (defined('CURLOPT_PROXYAUTH')) { // any proxy authentication if PHP 5.1 curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM); } } } // set up header and content handlers $received = new stdClass(); $received->headers = array(); // received headers array $received->tofile = $tofile; $received->fh = null; curl_setopt($ch, CURLOPT_HEADERFUNCTION, partial('download_file_content_header_handler', $received)); if ($tofile) { curl_setopt($ch, CURLOPT_WRITEFUNCTION, partial('download_file_content_write_handler', $received)); } if (!isset($CFG->curltimeoutkbitrate)) { //use very slow rate of 56kbps as a timeout speed when not set $bitrate = 56; } else { $bitrate = $CFG->curltimeoutkbitrate; } // try to calculate the proper amount for timeout from remote file size. // if disabled or zero, we won't do any checks nor head requests. if ($calctimeout && $bitrate > 0) { //setup header request only options curl_setopt_array($ch, array(CURLOPT_RETURNTRANSFER => false, CURLOPT_NOBODY => true)); curl_exec($ch); $info = curl_getinfo($ch); $err = curl_error($ch); if ($err === '' && $info['download_content_length'] > 0) { //no curl errors $timeout = max($timeout, ceil($info['download_content_length'] * 8 / ($bitrate * 1024))); //adjust for large files only - take max timeout. } //reinstate affected curl options curl_setopt_array($ch, array(CURLOPT_RETURNTRANSFER => true, CURLOPT_NOBODY => false)); } curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); $result = curl_exec($ch); // try to detect encoding problems if ((curl_errno($ch) == 23 or curl_errno($ch) == 61) and defined('CURLOPT_ENCODING')) { curl_setopt($ch, CURLOPT_ENCODING, 'none'); $result = curl_exec($ch); } if ($received->fh) { fclose($received->fh); } if (curl_errno($ch)) { $error = curl_error($ch); $error_no = curl_errno($ch); curl_close($ch); if ($fullresponse) { $response = new stdClass(); if ($error_no == 28) { $response->status = '-100'; // mimic snoopy } else { $response->status = '0'; } $response->headers = array(); $response->response_code = $error; $response->results = false; $response->error = $error; return $response; } else { debugging("cURL request for \"{$url}\" failed with: {$error} ({$error_no})", DEBUG_ALL); return false; } } else { $info = curl_getinfo($ch); curl_close($ch); if (empty($info['http_code'])) { // for security reasons we support only true http connections (Location: file:// exploit prevention) $response = new stdClass(); $response->status = '0'; $response->headers = array(); $response->response_code = 'Unknown cURL error'; $response->results = false; // do NOT change this, we really want to ignore the result! $response->error = 'Unknown cURL error'; } else { $response = new stdClass(); $response->status = (string) $info['http_code']; $response->headers = $received->headers; $response->response_code = $received->headers[0]; $response->results = $result; $response->error = ''; } if ($fullresponse) { return $response; } else { if ($info['http_code'] != 200) { debugging("cURL request for \"{$url}\" failed, HTTP response code: " . $response->response_code, DEBUG_ALL); return false; } else { return $response->results; } } } }
/** * Set options for individual curl instance * * @param resource $curl A curl handle * @param array $options * @return resource The curl handle */ private function apply_opt($curl, $options) { // Some more security first. if (defined('CURLOPT_PROTOCOLS')) { $this->options['CURLOPT_PROTOCOLS'] = CURLPROTO_HTTP | CURLPROTO_HTTPS; } if (defined('CURLOPT_REDIR_PROTOCOLS')) { $this->options['CURLOPT_REDIR_PROTOCOLS'] = CURLPROTO_HTTP | CURLPROTO_HTTPS; } // Clean up $this->cleanopt(); // set cookie if (!empty($this->cookie) || !empty($options['cookie'])) { $this->setopt(array('cookiejar' => $this->cookie, 'cookiefile' => $this->cookie)); } // Bypass proxy if required. if ($this->proxy === null) { if (!empty($this->options['CURLOPT_URL']) and is_proxybypass($this->options['CURLOPT_URL'])) { $proxy = false; } else { $proxy = true; } } else { $proxy = (bool) $this->proxy; } // Set proxy. if ($proxy) { $options['CURLOPT_PROXY'] = $this->proxy_host; } else { unset($this->options['CURLOPT_PROXY']); } $this->setopt($options); // reset before set options curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, 'formatHeader')); // set headers if (empty($this->header)) { $this->setHeader(array('User-Agent: MoodleBot/1.0', 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Connection: keep-alive')); } curl_setopt($curl, CURLOPT_HTTPHEADER, $this->header); if ($this->debug) { echo '<h1>Options</h1>'; var_dump($this->options); echo '<h1>Header</h1>'; var_dump($this->header); } // Do not allow infinite redirects. if (!isset($this->options['CURLOPT_MAXREDIRS'])) { $this->options['CURLOPT_MAXREDIRS'] = 0; } else { if ($this->options['CURLOPT_MAXREDIRS'] > 100) { $this->options['CURLOPT_MAXREDIRS'] = 100; } else { $this->options['CURLOPT_MAXREDIRS'] = (int) $this->options['CURLOPT_MAXREDIRS']; } } // Make sure we always know if redirects expected. if (!isset($this->options['CURLOPT_FOLLOWLOCATION'])) { $this->options['CURLOPT_FOLLOWLOCATION'] = 0; } // Set options. foreach ($this->options as $name => $val) { if ($name === 'CURLOPT_PROTOCOLS' or $name === 'CURLOPT_REDIR_PROTOCOLS') { // These can not be changed, sorry. continue; } if ($name === 'CURLOPT_FOLLOWLOCATION' and $this->emulateredirects) { // The redirects are emulated elsewhere. curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 0); continue; } $name = constant($name); curl_setopt($curl, $name, $val); } return $curl; }
/** * Connect to the CAS (clientcas connection or proxycas connection) * */ function connectCAS() { global $CFG; static $connected = false; if (!$connected) { // Make sure phpCAS doesn't try to start a new PHP session when connecting to the CAS server. if ($this->config->proxycas) { phpCAS::proxy($this->config->casversion, $this->config->hostname, (int) $this->config->port, $this->config->baseuri, false); } else { phpCAS::client($this->config->casversion, $this->config->hostname, (int) $this->config->port, $this->config->baseuri, false); } $connected = true; } // If Moodle is configured to use a proxy, phpCAS needs some curl options set. if (!empty($CFG->proxyhost) && !is_proxybypass($this->config->hostname)) { phpCAS::setExtraCurlOption(CURLOPT_PROXY, $CFG->proxyhost); if (!empty($CFG->proxyport)) { phpCAS::setExtraCurlOption(CURLOPT_PROXYPORT, $CFG->proxyport); } if (!empty($CFG->proxytype)) { // Only set CURLOPT_PROXYTYPE if it's something other than the curl-default http if ($CFG->proxytype == 'SOCKS5') { phpCAS::setExtraCurlOption(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } } if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) { phpCAS::setExtraCurlOption(CURLOPT_PROXYUSERPWD, $CFG->proxyuser . ':' . $CFG->proxypassword); if (defined('CURLOPT_PROXYAUTH')) { // any proxy authentication if PHP 5.1 phpCAS::setExtraCurlOption(CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM); } } } if ($this->config->certificate_check && $this->config->certificate_path) { phpCAS::setCasServerCACert($this->config->certificate_path); } else { // Don't try to validate the server SSL credentials phpCAS::setNoCasServerValidation(); } }
/** * Get the remote machine's SSL Cert * * @param string $uri The URI of a file on the remote computer, including * its http:// or https:// prefix * @return string A PEM formatted SSL Certificate. */ function mnet_get_public_key($uri, $application=null) { global $CFG, $DB; $mnet = get_mnet_environment(); // The key may be cached in the mnet_set_public_key function... // check this first $key = mnet_set_public_key($uri); if ($key != false) { return $key; } if (empty($application)) { $application = $DB->get_record('mnet_application', array('name'=>'moodle')); } $rq = xmlrpc_encode_request('system/keyswap', array($CFG->wwwroot, $mnet->public_key, $application->name), array("encoding" => "utf-8")); $ch = curl_init($uri . $application->xmlrpc_server_url); curl_setopt($ch, CURLOPT_TIMEOUT, 60); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Moodle'); curl_setopt($ch, CURLOPT_POSTFIELDS, $rq); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml charset=UTF-8")); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // check for proxy if (!empty($CFG->proxyhost) and !is_proxybypass($uri)) { // SOCKS supported in PHP5 only if (!empty($CFG->proxytype) and ($CFG->proxytype == 'SOCKS5')) { if (defined('CURLPROXY_SOCKS5')) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } else { curl_close($ch); print_error( 'socksnotsupported','mnet' ); } } curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false); if (empty($CFG->proxyport)) { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost); } else { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost.':'.$CFG->proxyport); } if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $CFG->proxyuser.':'.$CFG->proxypassword); if (defined('CURLOPT_PROXYAUTH')) { // any proxy authentication if PHP 5.1 curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM); } } } $res = xmlrpc_decode(curl_exec($ch)); // check for curl errors $curlerrno = curl_errno($ch); if ($curlerrno!=0) { debugging("Request for $uri failed with curl error $curlerrno"); } // check HTTP error code $info = curl_getinfo($ch); if (!empty($info['http_code']) and ($info['http_code'] != 200)) { debugging("Request for $uri failed with HTTP code ".$info['http_code']); } curl_close($ch); if (!is_array($res)) { // ! error $public_certificate = $res; $credentials=array(); if (strlen(trim($public_certificate))) { $credentials = openssl_x509_parse($public_certificate); $host = $credentials['subject']['CN']; if (array_key_exists( 'subjectAltName', $credentials['subject'])) { $host = $credentials['subject']['subjectAltName']; } if (strpos($uri, $host) !== false) { mnet_set_public_key($uri, $public_certificate); return $public_certificate; } else { debugging("Request for $uri returned public key for different URI - $host"); } } else { debugging("Request for $uri returned empty response"); } } else { debugging( "Request for $uri returned unexpected result"); } return false; }
/** * Fetches content of file from Internet (using proxy if defined). Uses cURL extension if present. * Due to security concerns only downloads from http(s) sources are supported. * * @param string $url file url starting with http(s):// * @param array $headers http headers, null if none. If set, should be an * associative array of header name => value pairs. * @param array $postdata array means use POST request with given parameters * @param bool $fullresponse return headers, responses, etc in a similar way snoopy does * (if false, just returns content) * @param int $timeout timeout for complete download process including all file transfer * (default 5 minutes) * @param int $connecttimeout timeout for connection to server; this is the timeout that * usually happens if the remote server is completely down (default 20 seconds); * may not work when using proxy * @param bool $skipcertverify If true, the peer's SSL certificate will not be checked. Only use this when already in a trusted location. * @return mixed false if request failed or content of the file as string if ok. */ function download_file_content($url, $headers = null, $postdata = null, $fullresponse = false, $timeout = 300, $connecttimeout = 20, $skipcertverify = false) { global $CFG; // some extra security $newlines = array("\r", "\n"); if (is_array($headers)) { foreach ($headers as $key => $value) { $headers[$key] = str_replace($newlines, '', $value); } } $url = str_replace($newlines, '', $url); if (!preg_match('|^https?://|i', $url)) { if ($fullresponse) { $response = new object(); $response->status = 0; $response->headers = array(); $response->response_code = 'Invalid protocol specified in url'; $response->results = ''; $response->error = 'Invalid protocol specified in url'; return $response; } else { return false; } } // check if proxy (if used) should be bypassed for this url $proxybypass = is_proxybypass($url); if (!($ch = curl_init($url))) { debugging('Can not init curl.'); return false; } // set extra headers if (is_array($headers)) { $headers2 = array(); foreach ($headers as $key => $value) { $headers2[] = "{$key}: {$value}"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headers2); } if ($skipcertverify) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); } // use POST if requested if (is_array($postdata)) { foreach ($postdata as $k => $v) { $postdata[$k] = urlencode($k) . '=' . urlencode($v); } $postdata = implode('&', $postdata); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connecttimeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); if (!ini_get('open_basedir') and !ini_get('safe_mode')) { // TODO: add version test for '7.10.5' curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); } if (!empty($CFG->proxyhost) and !$proxybypass) { // SOCKS supported in PHP5 only if (!empty($CFG->proxytype) and $CFG->proxytype == 'SOCKS5') { if (defined('CURLPROXY_SOCKS5')) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } else { curl_close($ch); if ($fullresponse) { $response = new object(); $response->status = '0'; $response->headers = array(); $response->response_code = 'SOCKS5 proxy is not supported in PHP4'; $response->results = ''; $response->error = 'SOCKS5 proxy is not supported in PHP4'; return $response; } else { debugging("SOCKS5 proxy is not supported in PHP4.", DEBUG_ALL); return false; } } } curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false); if (empty($CFG->proxyport)) { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost); } else { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost . ':' . $CFG->proxyport); } if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $CFG->proxyuser . ':' . $CFG->proxypassword); if (defined('CURLOPT_PROXYAUTH')) { // any proxy authentication if PHP 5.1 curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM); } } } $data = curl_exec($ch); // try to detect encoding problems if ((curl_errno($ch) == 23 or curl_errno($ch) == 61) and defined('CURLOPT_ENCODING')) { curl_setopt($ch, CURLOPT_ENCODING, 'none'); $data = curl_exec($ch); } if (curl_errno($ch)) { $error = curl_error($ch); $error_no = curl_errno($ch); curl_close($ch); if ($fullresponse) { $response = new object(); if ($error_no == 28) { $response->status = '-100'; // mimic snoopy } else { $response->status = '0'; } $response->headers = array(); $response->response_code = $error; $response->results = ''; $response->error = $error; return $response; } else { debugging("cURL request for \"{$url}\" failed with: {$error} ({$error_no})", DEBUG_ALL); return false; } } else { $info = curl_getinfo($ch); curl_close($ch); if (empty($info['http_code'])) { // for security reasons we support only true http connections (Location: file:// exploit prevention) $response = new object(); $response->status = '0'; $response->headers = array(); $response->response_code = 'Unknown cURL error'; $response->results = ''; // do NOT change this! $response->error = 'Unknown cURL error'; } else { // strip redirect headers and get headers array and content $data = explode("\r\n\r\n", $data, $info['redirect_count'] + 2); $results = array_pop($data); $headers = array_pop($data); $headers = explode("\r\n", trim($headers)); $response = new object(); $response->status = (string) $info['http_code']; $response->headers = $headers; $response->response_code = $headers[0]; $response->results = $results; $response->error = ''; } if ($fullresponse) { return $response; } else { if ($info['http_code'] != 200) { debugging("cURL request for \"{$url}\" failed, HTTP response code: " . $response->response_code, DEBUG_ALL); return false; } else { return $response->results; } } } }
/** * Set options for individual curl instance * * @param resource $curl A curl handle * @param array $options * @return resource The curl handle */ private function apply_opt($curl, $options) { // Clean up $this->cleanopt(); // set cookie if (!empty($this->cookie) || !empty($options['cookie'])) { $this->setopt(array('cookiejar' => $this->cookie, 'cookiefile' => $this->cookie)); } // set proxy if (!empty($this->proxy) || !empty($options['proxy'])) { $this->setopt($this->proxy); } $this->setopt($options); // reset before set options curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, 'formatHeader')); // set headers if (empty($this->header)) { $this->setHeader(array('User-Agent: MoodleBot/1.0', 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Connection: keep-alive')); } curl_setopt($curl, CURLOPT_HTTPHEADER, $this->header); // Bypass proxy (for this request only) if required. if (!empty($this->options['CURLOPT_URL']) && is_proxybypass($this->options['CURLOPT_URL'])) { unset($this->options['CURLOPT_PROXY']); } if ($this->debug) { echo '<h1>Options</h1>'; var_dump($this->options); echo '<h1>Header</h1>'; var_dump($this->header); } // Set options. foreach ($this->options as $name => $val) { $name = constant(strtoupper($name)); curl_setopt($curl, $name, $val); } return $curl; }
/** * Makes API requests using cURL and a signed header * @param String $method * The API method to which the request is going to be made * @param mixed $parameters * The parameters of the API request can be either an associative array or simple data types * @return mixed $result * An array of data when the API request was successful, false on error. * Make sure you use the identical operator to check the response (!==FALSE) some response may be 0 * @throws moodle_exception * The required configuration parameters of the API are not set */ public function newServiceCall($method, $parameters = null) { global $USER, $CFG; //Test if connection settings have the correct format $config_fields = array('filter_babelium_serverdomain', 'filter_babelium_serverport', 'filter_babelium_apidomain', 'filter_babelium_apiendpoint', 'filter_babelium_accesskey', 'filter_babelium_secretaccesskey'); foreach ($config_fields as $cfield) { if (!isset($CFG->{$cfield}) || empty($CFG->{$cfield})) { $this->display_error('babeliumErrorConfigParameters'); } if ($cfield == 'filter_babelium_accesskey' && strlen($CFG->{$cfield}) != 20 || $cfield == 'filter_babelium_secretaccesskey' && strlen($CFG->{$cfield}) != 40) { $this->display_error('babeliumErrorConfigParameters'); } } $commProtocol = 'http://'; $request = array(); $request['method'] = $method; if ($parameters != null && is_array($parameters) && count($parameters) > 0) { $request['parameters'] = $parameters; } //Date timestamp formated following one of the standards allowed for HTTP 1.1 date headers (DATE_RFC1123) $date = date("D, d M Y H:i:s O"); $referer = $_SERVER['HTTP_REFERER']; $pieces = parse_url($referer); $originhost = $_SERVER['HTTP_HOST']; $origin = $pieces['scheme'] . "://" . $originhost; $request['header']['date'] = $date; $signature = "BMP " . $CFG->filter_babelium_accesskey . ":" . $this->generateAuthorization($method, $date, $originhost, $CFG->filter_babelium_secretaccesskey); $request['header']['authorization'] = $signature; //See this workaround if the query parameters are written with & : http://es.php.net/manual/es/function.http-build-query.php#102324 $request = http_build_query($request, '', '&'); $web_domain = $CFG->filter_babelium_serverdomain; $api_domain = $CFG->filter_babelium_apidomain; $api_endpoint = $CFG->filter_babelium_apiendpoint; $api_url = $commProtocol . $api_domain . '/' . $api_endpoint; $query_string = $api_url . '?' . $method; //Check if proxy (if used) should be bypassed for this url $proxybypass = function_exists('is_proxybypass') ? is_proxybypass($query_string) : false; //Prepare the cURL request if (!($ch = curl_init($query_string))) { debugging('Can not init curl.'); return false; } //curl_setopt($ch, CURLOPT_URL, $query_string); curl_setopt($ch, CURLOPT_POSTFIELDS, $request); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_REFERER, $referer); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Origin: {$origin}")); //Check for proxy configuration if (!empty($CFG->proxyhost) and !$proxybypass) { // SOCKS supported in PHP5 only if (!empty($CFG->proxytype) and $CFG->proxytype == 'SOCKS5') { if (defined('CURLPROXY_SOCKS5')) { curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } else { curl_close($ch); debugging("SOCKS5 proxy is not supported in PHP4.", DEBUG_ALL); return false; } } curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false); if (empty($CFG->proxyport)) { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost); } else { curl_setopt($ch, CURLOPT_PROXY, $CFG->proxyhost . ':' . $CFG->proxyport); } if (!empty($CFG->proxyuser) and !empty($CFG->proxypassword)) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $CFG->proxyuser . ':' . $CFG->proxypassword); if (defined('CURLOPT_PROXYAUTH')) { // any proxy authentication if PHP 5.1 curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM); } } } $result = curl_exec($ch); curl_close($ch); //Parses the response output to separate the headers from the body of the response $this->parseCurlOutput($result); //Add the service call to the activity log to better track down possible problems $this->activity_log($USER->id, $USER->username, "service_call", $query_string, $method, is_array($parameters) ? implode('&', $parameters) : $parameters, $date, $_SERVER['HTTP_HOST'], $signature, $this->_curlHeaderHttpStatusCode, $this->_curlHeaderHttpStatusMessage); //If the body of the response is empty or the HTTP status code is not 200 display an error message if (!$this->_curlResponse || $this->_curlHeaderHttpStatusCode != 200) { $this->display_error('babeliumApiErrorCode' . $this->_curlHeaderHttpStatusCode); } $result = json_decode($this->_curlResponse, true); if ($result['status'] == 'success' && $result['response']) { $result = $result['response']; } else { $result = false; } return $result; }
/** * fire a cron URL using CURL. * * */ function fire_vhost_cron($vhost) { global $VCRON, $DB; if ($VCRON->TRACE_ENABLE) { $CRONTRACE = fopen($VCRON->TRACE, 'a'); } $ch = curl_init($vhost->root_web . '/main/cron/run.php'); $http_proxy_host = api_get_setting('vchamilo_httpproxyhost', 'vchamilo'); $http_proxy_port = api_get_setting('vchamilo_httpproxyport', 'vchamilo'); $http_proxy_bypass = api_get_setting('vchamilo_httpproxybypass', 'vchamilo'); $http_proxy_user = api_get_setting('vchamilo_httpproxyuser', 'vchamilo'); $http_proxy_password = api_get_setting('vchamilo_httpproxypassword', 'vchamilo'); curl_setopt($ch, CURLOPT_TIMEOUT, $VCRON->TIMEOUT); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Chamilo'); curl_setopt($ch, CURLOPT_POSTFIELDS, ''); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml charset=UTF-8")); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // Check for proxy. if (!empty($http_proxy_host) and !is_proxybypass($uri)) { curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false); if (empty($http_proxy_port)) { echo "Using proxy {$http_proxy_host}\n"; curl_setopt($ch, CURLOPT_PROXY, $http_proxy_host); } else { echo "Using proxy {$http_proxy_host}:{$http_proxy_port}\n"; curl_setopt($ch, CURLOPT_PROXY, $http_proxy_host . ':' . $http_proxy_port); } if (!empty($http_proxy_user) and !empty($http_proxy_password)) { curl_setopt($ch, CURLOPT_PROXYUSERPWD, $http_proxy_user . ':' . $http_proxy_password); if (defined('CURLOPT_PROXYAUTH')) { // any proxy authentication if PHP 5.1 curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM); } } } $timestamp_send = time(); $rawresponse = curl_exec($ch); $timestamp_receive = time(); if ($rawresponse === false) { $error = curl_errno($ch) . ':' . curl_error($ch); if ($VCRON->TRACE_ENABLE) { if ($CRONTRACE) { fputs($CRONTRACE, "VCron start on {$vhost->root_web} : " . api_time_to_hms($timestamp_send) . "\n"); fputs($CRONTRACE, "VCron Error : {$error} \n"); fputs($CRONTRACE, "VCron stop on {$vhost->root_web} : {$timestamp_receive}\n#################\n\n"); fclose($CRONTRACE); } } echo "VCron started on {$vhost->root_web} : " . api_time_to_hms($timestamp_send) . "\n"; echo "VCron Error : {$error} \n"; echo "VCron stop on {$vhost->root_web} : " . api_time_to_hms($timestamp_receive) . "\n#################\n\n"; return false; } if ($VCRON->TRACE_ENABLE) { if ($CRONTRACE) { fputs($CRONTRACE, "VCron start on {$vhost->vhostname} : " . api_time_to_hms($timestamp_send) . "\n"); fputs($CRONTRACE, $rawresponse . "\n"); fputs($CRONTRACE, "VCron stop on {$vhost->vhostname} : " . api_time_to_hms($timestamp_receive) . "\n#################\n\n"); fclose($CRONTRACE); } } echo "VCron start on {$vhost->root_web} : " . api_time_to_hms($timestamp_send) . "\n"; echo $rawresponse . "\n"; echo "VCron stop on {$vhost->root_web} : " . api_time_to_hms($timestamp_receive) . "\n#################\n\n"; $vhost->lastcrongap = time() - $vhost->lastcron; $vhost->lastcron = $timestamp_send; $vhost->croncount++; $vhostid = $vhost->id; unset($vhost->id); Database::update('vchamilo', (array) $vhost, array('id = ?' => $vhostid)); }