. * * Portions created by the Initial Developer are Copyright (C) 2004 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ require_once('../config.inc.php'); require_once($config['base_path'].'/includes/iolib.inc.php'); require_once($config['base_path'].'/includes/db.inc.php'); require_once($config['base_path'].'/includes/contrib/nusoap/lib/nusoap.php'); // Turn off Error Reporting because it breaks xml formatting and causes errors error_reporting(0); if($config['debug']){ $debug = 1; } // Create the server instance $server = new soap_server; // UTF-8 support is good $server->soap_defencoding = "UTF-8"; $server->decode_utf8 = false; // WSDL Support if($config['use_wsdl']){ $server->configureWSDL('reporterwsdl', 'urn:reporterwsdl'); } // Register the method to expose // Note: with NuSOAP 0.6.3, only method name is used w/o WSDL $server->register( 'register', // method name array('language' => 'xsd:string',), // input parameters array('return' => 'xsd:string'), // output parameters 'uri:MozillaReporter', // namespace 'uri:MozillaReporter/register', // SOAPAction 'rpc', // style 'encoded' // use ); $server->register( 'submitReport', // method name array('rmoVers' => 'xsd:string', 'url' => 'xsd:string', 'problem_type' => 'xsd:string', 'description' => 'xsd:string', 'behind_login' => 'xsd:string', 'platform' => 'xsd:string', 'oscpu' => 'xsd:string', 'gecko' => 'xsd:string', 'product' => 'xsd:string', 'useragent' => 'xsd:string', 'buildconfig' => 'xsd:string', 'language' => 'xsd:string', 'email' => 'xsd:string', 'sysid' => 'xsd:string', 'screenshot' => 'xsd:base64Binary', 'screenshot_format' => 'xsd:string'), // input parameters array('return' => 'xsd:string'), // output parameters 'uri:MozillaReporter', // namespace 'uri:MozillaReporter/submitReport', // SOAPAction 'rpc', // style 'encoded' // use ); function submitReport($rmoVers, $url, $problem_type, $description, $behind_login, $platform, $oscpu, $gecko, $product, $useragent, $buildconfig, $language, $email, $sysid, $screenshot, $screenshot_format) { global $config; if ($config['service_active'] == false){ return new soap_fault('SERVER', '', 'The service is currently unavailable. Please try again in a few minutes.'); } /********** * Sanitize and Validate **********/ // Remove any HTML tags and whitespace $rmoVers = trim(strip_all_tags($rmoVers)); $url = trim(strip_all_tags($url)); $problem_type = trim(strip_all_tags($problem_type)); $description = trim(strip_all_tags($description)); $behind_login = trim(strip_all_tags($behind_login)); $platform = trim(strip_all_tags($platform)); $oscpu = trim(strip_all_tags($oscpu)); $gecko = trim(strip_all_tags($gecko)); $product = trim(strip_all_tags($product)); $useragent = trim(strip_all_tags($useragent)); $buildconfig = trim(strip_all_tags($buildconfig)); $language = trim(strip_all_tags($language)); $email = trim(strip_all_tags($email)); $sysid = trim(strip_all_tags($sysid)); $screenshot_format = trim(strip_all_tags($screenshot_format)); $screenshot_width = trim(strip_all_tags($screenshot_width)); $screenshot_height = trim(strip_all_tags($screenshot_height)); // check verison if ($rmoVers < $config['min_vers']){ return new soap_fault('Client', '', 'Your product is out of date, please upgrade. See http://reporter.mozilla.org/install for details.', $rmoVers); } $parsedUrl = parse_url($url); if (!$url || !$parsedUrl['host']){ return new soap_fault('Client', '', 'url must use a valid URL syntax http://mozilla.com/page', $url); } if (!$problem_type || $problem_type == -1 || $problem_type == "0") { } if ($behind_login != 1 && $behind_login != 0) { return new soap_fault('Client', '', 'behind_login must be type bool int', $behind_login); } if (!$platform) { return new soap_fault('Client', '', 'Invalid Platform Type', $platform); } if (!$product) { return new soap_fault('Client', '', 'Invalid Product', $product); } if (!$language) { return new soap_fault('Client', '', 'Invalid Localization', $language); } /* We don't explicity require this since some older clients may not return this. if (!$gecko) { return new soap_fault('Client', '', 'Invalid Gecko ID', $gecko); } */ if (!$oscpu) { return new soap_fault('Client', '', 'Invalid OS CPU', $oscpu); } if (!$useragent) { return new soap_fault('Client', '', 'Invalid Useragent', $useragent); } if (!$buildconfig) { return new soap_fault('Client', '', 'Invalid Build Config', $buildconfig); } if (!$sysid) { return new soap_fault('Client', '', 'No SysID Entered', $sysid); } /* We don't require email... it's optional if (!$email) { return new soap_fault('Client', '', 'Invalid Email', $email); } */ // Image Validation if($screenshot != null) { // If no format specified, it's invalid if($screenshot_format == null) { return new soap_fault('Client', '', 'Invalid Screenshot', $screenshot_format); } // Must be in our list of approved formats. if(!in_array($screenshot_format, $config['screenshot_imageTypes'])){ return new soap_fault('Client', '', 'Invalid Screenshot Format', $screenshot_format); } } // create report_id. We just MD5 it, becase we don't need people counting reports, since it's inaccurate. // we can have dup's, so it's not a good thing for people to be saying 'mozilla.org reports 500,000 incompatable sites' $report_id = 'RMO'.str_replace(".", "", array_sum(explode(' ', microtime()))); /********** * Open DB **********/ $db = NewDBConnection($config['db_dsn']); $db->SetFetchMode(ADODB_FETCH_ASSOC); /********** * Check for valid sysid **********/ $sysIdQuery = $db->Execute("SELECT sysid.sysid_id FROM sysid WHERE sysid.sysid_id = ".$db->quote($sysid)); if(!$sysIdQuery){ return new soap_fault('SERVER', '', 'Database Error SR1'); } if ($sysIdQuery->RecordCount() != 1){ return new soap_fault('Client', '', 'Invalid SysID', $sysid); } /********** * Check Hostname **********/ $hostnameQuery = $db->Execute("SELECT host.host_id FROM host WHERE host.host_hostname = ".$db->quote($parsedUrl['host'])); if(!$hostnameQuery){ return new soap_fault('SERVER', '', 'Database Error SR2'); } /********** * Add Host **********/ if ($hostnameQuery->RecordCount() <= 0) { // generate hash $host_id = md5($parsedUrl['host'].microtime()); // We add the URL $addUrlQuery = $db->Execute("INSERT INTO host (host.host_id, host.host_hostname, host.host_date_added) VALUES ( ".$db->quote($host_id).", ".$db->quote($parsedUrl['host']).", now() )"); if (!$addUrlQuery) { return new soap_fault('SERVER', '', 'Database Error SR3'); } } else if ($hostnameQuery->RecordCount() == 1) { // pull the hash from DB $host_id = $hostnameQuery->fields['host_id']; } else{ return new soap_fault('SERVER', '', 'Host Exception Error'); } /********** * Add Report **********/ $addReportQuery = $db->Execute("INSERT INTO report ( report.report_id, report.report_url, report.report_host_id, report.report_problem_type, report.report_description, report.report_behind_login, report.report_useragent, report.report_platform, report.report_oscpu, report.report_language, report.report_gecko, report.report_buildconfig, report.report_product, report.report_email, report.report_ip, report.report_file_date, report.report_sysid ) VALUES ( ".$db->quote($report_id).", ".$db->quote($url).", ".$db->quote($host_id).", ".$db->quote($problem_type).", ".$db->quote($description).", ".$db->quote($behind_login).", ".$db->quote($useragent).", ".$db->quote($platform).", ".$db->quote($oscpu).", ".$db->quote($language).", ".$db->quote($gecko).", ".$db->quote($buildconfig).", ".$db->quote($product).", ".$db->quote($email).", ".$db->quote($_SERVER['REMOTE_ADDR']).", now(), ".$db->quote($sysid)." );"); if (!$addReportQuery) { return new soap_fault('SERVER', '', 'Database Error SR4'); } /********** * Process Screenshot **********/ if($screenshot != null){ // Screenshots come in base64 encoded, so we need to decode. $screenshot = base64_decode($screenshot); // Note we addslashes() not quote() the image, because quote() is not // binary compatible and has ugly consequences. $insertSsQuery = $db->Execute("INSERT screenshot( screenshot.screenshot_report_id, screenshot.screenshot_data, screenshot.screenshot_format ) VALUES (".$db->quote($report_id).", '".addslashes($screenshot)."', ".$db->quote($screenshot_format)." ); "); if(!$insertSsQuery){ return new soap_fault('SERVER', '', 'Database Error SR5'); } // If we got this far, the screenshot was successfully added! } /********** * Disconnect (optional really) **********/ $db->disconnect(); return $report_id; } function register($language){ global $config; /********** * Open DB **********/ $db = NewDBConnection($config['db_dsn']); $db->SetFetchMode(ADODB_FETCH_ASSOC); /********** * Generate an ID **********/ $unique = false; // in theory a collision could happen, though unlikely. So just to make sure, we do this // since that would really suck while (!$unique) { $id = date("ymd").rand(1000,9999); $uniqueQuery =& $db->Execute("SELECT sysid.sysid_id FROM sysid WHERE sysid.sysid_id = '$id' "); if(!$uniqueQuery){ return new soap_fault('SERVER', '', 'Database Error R1'); } $numRows = $uniqueQuery->RecordCount(); if ($numRows == 0) { // It's unique, stop the loop. $unique = true; } } /********** * Register ID **********/ $addSysIdQuery = $db->Execute("INSERT INTO sysid ( sysid.sysid_id, sysid.sysid_created, sysid.sysid_created_ip, sysid.sysid_language ) VALUES ( '".$id."', now(), '".$_SERVER['REMOTE_ADDR']."', ".$db->quote($language)." )"); if (!$addSysIdQuery) { return new soap_fault('SERVER', '', 'Database Error R2'); } /********** * Disconnect **********/ $db->disconnect(); return $id; } // Use the request to (try to) invoke the service $HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ''; $server->service($HTTP_RAW_POST_DATA); ?>