"Fossies" - the Fresh Open Source Software Archive

Member "z-push/index.php" (2 Aug 2013, 17574 Bytes) of package /linux/www/old/group-e_z-push_v3.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "index.php" see the Fossies "Dox" file reference documentation.

A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.


    1 <?php
    2 /***********************************************
    3 * File      :   index.php
    4 * Project   :   Z-Push
    5 * Descr     :   This is the entry point
    6 *               through which all requests
    7 *               are called.
    8 *
    9 * Created   :   01.10.2007
   10 *
   11 *  Zarafa Deutschland GmbH, www.zarafaserver.de
   12 * This file is distributed under GPL v2.
   13 * Consult LICENSE file for details
   14 ************************************************/
   15 
   16 $sessionstarttime = microtime(true);
   17 //we handle connection aborts ourself. necessary to keep sync state clean in heartbeat/wait
   18 ignore_user_abort(true);
   19 ob_start(false, 1048576);
   20 
   21 include_once('zpushdefs.php');
   22 include_once("config.php");
   23 include_once("proto.php");
   24 include_once("request.php");
   25 include_once("debug.php");
   26 include_once("compat.php");
   27 include_once("version.php");
   28 
   29 // Define SCRIPT_TIMEOUT in case it is not defined in config.php or negative if you substract 600
   30 if (!defined("SCRIPT_TIMEOUT")) {
   31     define('REAL_SCRIPT_TIMEOUT', 3540+600);
   32 } else {
   33     if ((SCRIPT_TIMEOUT-600) < 660) 
   34         define('REAL_SCRIPT_TIMEOUT', SCRIPT_TIMEOUT+660);
   35     else 
   36         define('REAL_SCRIPT_TIMEOUT', SCRIPT_TIMEOUT);
   37 }
   38 
   39 // Attempt to set maximum execution time
   40 ini_set('max_execution_time', REAL_SCRIPT_TIMEOUT);
   41 set_time_limit(REAL_SCRIPT_TIMEOUT);
   42 
   43 
   44 debugLog("Start ------ THIS IS AN UNOFFICIAL DEVELOPER VERSION!");
   45 debugLog("Z-Push version: $zpush_version");
   46 debugLog("Client IP: ". $_SERVER['REMOTE_ADDR']);
   47 debugLog("Set max_execution_time to ". ini_get('max_execution_time'));
   48 //debugLog(print_r($_SERVER,true));
   49 //debugLog(print_r($_GET,true));
   50 //debugLog(print_r($_POST,true));
   51 //debugLog(print_r(apache_request_headers(),true));
   52 register_shutdown_function("shutdownCommunication");
   53 $cachestatus = SYNCCACHE_UNCHANGED; 
   54 $input = fopen("php://input", "r");
   55 $output = fopen("php://output", "w+");
   56 
   57 // The script must always be called with authorisation info
   58 
   59 if (!isset($_SERVER['PHP_AUTH_PW'])) {
   60     header("HTTP/1.1 401 Unauthorized");
   61     header("WWW-Authenticate: Basic realm=\"ZPush\"");
   62     print("Access denied. Please send authorisation information");
   63     debugLog("Access denied: no password sent.");
   64     debugLog("end");
   65     debugLog("--------");
   66     return;
   67 }
   68 
   69 // split username & domain if received as one
   70 if (($pos = strrpos($_SERVER['PHP_AUTH_USER'], '\\')) === false) {
   71     if (SEPARATE_UPN === true &&
   72         ($pos = strrpos($_SERVER['PHP_AUTH_USER'], '@')) !== false) {
   73         $auth_user = substr($_SERVER['PHP_AUTH_USER'],0,$pos);
   74         $auth_domain = substr($_SERVER['PHP_AUTH_USER'],$pos+1);
   75     } else {
   76         $auth_user = $_SERVER['PHP_AUTH_USER'];
   77         $auth_domain = '';
   78     }
   79 } else {
   80     $auth_domain = substr($_SERVER['PHP_AUTH_USER'],0,$pos);
   81     $auth_user = substr($_SERVER['PHP_AUTH_USER'],$pos+1);
   82 }
   83 
   84 
   85 $auth_pw = $_SERVER['PHP_AUTH_PW'];
   86 
   87 $cmd = $user = $devid = $devtype = "";
   88 
   89 // Parse the standard GET parameters
   90 if(isset($_GET["Cmd"]))
   91     $cmd = $_GET["Cmd"];
   92 if(isset($_GET["User"]))
   93     $user = $_GET["User"];
   94 if(isset($_GET["DeviceId"]))
   95     $devid = $_GET["DeviceId"];
   96 if(isset($_GET["DeviceType"]))
   97     $devtype = $_GET["DeviceType"];
   98 // Get the parameters from Query String in case they`re not in the get.
   99 // AS >=12.1
  100 if (!isset($_GET['Cmd']) &&
  101     !isset($_GET['DeviceId']) &&
  102     !isset($_GET['DeviceType']) &&
  103     isset($_SERVER['QUERY_STRING']) &&
  104     strlen($_SERVER['QUERY_STRING']) >= 10) {
  105     $user = $auth_user;
  106     $uri_decoded = base64uri_decode($_SERVER['QUERY_STRING']);
  107     $devid = $uri_decoded['DevID'];
  108     switch($uri_decoded['DevType']) {
  109         case 'PPC'  : $devtype = 'PocketPC'; break;
  110         case 'SP'   : $devtype = 'SmartPhone'; break;
  111     };
  112     switch($uri_decoded['Command']) {
  113         case '0'    : $cmd = 'Sync'; break;
  114         case '1'    : $cmd = 'SendMail'; break;
  115         case '2'    : $cmd = 'SmartForward'; break;
  116         case '3'    : $cmd = 'SmartReply'; break;
  117         case '4'    : $cmd = 'GetAttachment'; break;
  118         case '9'    : $cmd = 'FolderSync'; break;
  119         case '10'   : $cmd = 'FolderCreate'; break;
  120         case '11'   : $cmd = 'FolderDelete'; break;
  121         case '12'   : $cmd = 'FolderUpdate'; break;
  122         case '13'   : $cmd = 'MoveItems'; break;
  123         case '14'   : $cmd = 'GetItemEstimate'; break;
  124         case '15'   : $cmd = 'MeetingResponse'; break;
  125         case '16'   : $cmd = 'Search'; break;
  126         case '17'   : $cmd = 'Settings'; break;
  127         case '18'   : $cmd = 'Ping'; break;
  128         case '19'   : $cmd = 'ItemOperations'; break;
  129         case '20'   : $cmd = 'Provision'; break;
  130         case '21'   : $cmd = 'ResolveRecipients'; break;
  131         case '22'   : $cmd = 'ValidateCert'; break;
  132     }
  133     if (isset($uri_decoded['AttachmentName'])) $_GET['AttachmentName'] = $uri_decoded['AttachmentName'];
  134     if (isset($uri_decoded['ItemId'])) $_GET['ItemId'] = $uri_decoded['ItemId'];
  135     if (isset($uri_decoded['CollectionId'])) $_GET['CollectionId'] = $uri_decoded['CollectionId'];
  136     if (isset($uri_decoded['CollectionName'])) $_GET['CollectionName'] = $uri_decoded['CollectionName'];
  137     if (isset($uri_decoded['ParentId'])) $_GET['ParentId'] = $uri_decoded['ParentId'];
  138     if (isset($uri_decoded['LongId'])) $_GET['LongId'] = $uri_decoded['LongId'];
  139     if (isset($uri_decoded['Occurrence'])) $_GET['Occurrence'] = $uri_decoded['Occurrence'];
  140     if (isset($uri_decoded['Options'])) {
  141         $uri_decoded['Options'] = bin2hex($uri_decoded['Options'])*1;
  142         if($uri_decoded['Options'] & 0x01) debugLog("Save in sent Items");
  143         if($uri_decoded['Options'] & 0x02) debugLog("AcceptMultiPart");
  144     }
  145     if (isset($uri_decoded['User'])) $_GET['User'] = $uri_decoded['User'];
  146     debugLog('Base64 encoded URI contains: '.print_r($uri_decoded,true));
  147 };
  148 
  149 // The GET parameters are required
  150 if($_SERVER["REQUEST_METHOD"] == "POST") {
  151     if(!isset($user) || !isset($devid) || !isset($devtype)) {
  152         print("Your device requested the Z-Push URL without the required GET parameters");
  153         return;
  154     }
  155 }
  156 
  157 // Get the request headers so we can see the versions
  158 $requestheaders = apache_request_headers();
  159 if (isset($requestheaders["Ms-Asprotocolversion"])) 
  160     $requestheaders["MS-ASProtocolVersion"] = $requestheaders["Ms-Asprotocolversion"];
  161 if (isset($requestheaders["MS-ASProtocolVersion"]) ||
  162     isset($uri_decoded['ProtVer'])) {
  163     global $protocolversion;
  164     if (isset($requestheaders["MS-ASProtocolVersion"])) 
  165         $protocolversion = $requestheaders["MS-ASProtocolVersion"];
  166     else
  167         $protocolversion = $uri_decoded['ProtVer']/10;
  168     debugLog("Client supports version " . $protocolversion);
  169 } else {
  170     global $protocolversion;
  171 
  172     $protocolversion = "1.0";
  173 }
  174 
  175 // START ADDED dw2412 Support Multipart response
  176 //
  177 if ((isset($requestheaders["MS-ASAcceptMultiPart"]) &&
  178     $requestheaders["MS-ASAcceptMultiPart"] == "T") ||
  179     (isset($uri_decoded['Options']) && 
  180     $uri_decoded['Options'] & 0x02)) {
  181     $multipart = true;
  182 } else {
  183     $multipart = false;
  184 }
  185 // END ADDED dw2412 Support Multipart response
  186 
  187 //mthaler@endo7.com disable multipart for roadsync
  188 if (preg_match('/RoadSync/',$requestheaders['User-Agent'])) {
  189     debugLog('Disable Multipart: '.$requestheaders['User-Agent']);
  190     $multipart = false;
  191 }
  192 
  193 
  194 // START ADDED dw2412 Support gzip compression in result
  195 if (isset($requestheaders["Accept-Encoding"])) {
  196     $encodings = explode(", ",$requestheaders["Accept-Encoding"]);
  197     debugLog("Current zlib output compression setting: ".ini_get("zlib.output_compression"));
  198 
  199     if (array_search("gzip",$encodings) !== false &&
  200         function_exists('gzencode')) {
  201         ini_set("zlib.output_compression",'0');
  202         debugLog("Enabled zlib output compression");
  203         define ("GZIP_OUTPUT",true);
  204     } else {
  205         ini_set("zlib.output_compression",'0');
  206         debugLog("Disabled zlib output compression");
  207         define ("GZIP_OUTPUT",false);
  208     }
  209 } else {
  210     define ("GZIP_OUTPUT",false);
  211 }
  212 // END ADDED dw2412 Support gzip compression in result
  213 
  214 if (isset($requestheaders["X-Ms-Policykey"])) 
  215     $requestheaders["X-MS-PolicyKey"] = $requestheaders["X-Ms-Policykey"];
  216 if (isset($requestheaders["X-MS-PolicyKey"]) ||
  217     isset($uri_decoded['PolKey'])) {
  218     global $policykey;
  219     if (isset($requestheaders["X-MS-PolicyKey"])) 
  220         $policykey = $requestheaders["X-MS-PolicyKey"];
  221     else 
  222         $policykey = $uri_decoded['PolKey'];
  223 } else {
  224     global $policykey;
  225     $policykey = 0;
  226 }
  227 
  228 //get user agent
  229 if (isset($requestheaders["User-Agent"])) {
  230     global $useragent;
  231     $useragent = $requestheaders["User-Agent"];
  232 } else {
  233     global $useragent;
  234     $useragent = "unknown";
  235 }
  236 
  237 // if useragent starts with nokia limit message recipients - otherwise client will retrieve item unlimitted!!!
  238 if (strncmp($useragent,"Nokia",5) == 0) {
  239     debugLog("Nokia detected! Limit recipients to 100!");
  240     define("LIMIT_RECIPIENTS",100);
  241     define("NOKIA_DETECTED",true);
  242 }
  243 
  244 // Load our backend driver
  245 $backend_dir = opendir(BASE_PATH . "/backend");
  246 while($entry = readdir($backend_dir)) {
  247     if(substr($entry,0,1) == "." || substr($entry,-3) != "php")
  248         continue;
  249 
  250     if (!function_exists("mapi_logon") && ($entry == "ics.php"))
  251         continue;
  252 
  253     include_once(BASE_PATH . "/backend/" . $entry);
  254 }
  255 
  256 // Initialize our backend
  257 $backend = new $BACKEND_PROVIDER();
  258 
  259 if($backend->Logon($auth_user, $auth_domain, $auth_pw) == false) {
  260     header("HTTP/1.1 401 Unauthorized");
  261     header("WWW-Authenticate: Basic realm=\"ZPush\"");
  262     print("Access denied. Username or password incorrect.");
  263     debugLog("Access denied: backend logon failed.");
  264     debugLog("end");
  265     debugLog("--------");
  266     return;
  267 }
  268 //mthaler@endo7.com
  269 define('VERSION_SUPPORT','2.0,2.1,2.5,12.0,12.1');
  270 define('VERSION_SUPPORT_LAST','12.1');
  271 
  272 // check policy header 
  273            
  274 if (PROVISIONING === true && $_SERVER["REQUEST_METHOD"] != 'OPTIONS' && $cmd != 'Ping' && $cmd != 'Provision' && 
  275     $backend->CheckPolicy($policykey, $devid) != SYNC_PROVISION_STATUS_SUCCESS &&
  276     (LOOSE_PROVISIONING === false ||
  277     (LOOSE_PROVISIONING === true && (isset($requestheaders["X-MS-PolicyKey"]) || isset($uri_decoded['PolKey']) )))) {       
  278     header("HTTP/1.1 449 Retry after sending a PROVISION command");
  279     // dw2412 changed to support AS14 Protocol
  280     header("MS-Server-ActiveSync: ".VERSION_SUPPORT_LAST);
  281     header("MS-ASProtocolVersions: ".VERSION_SUPPORT);
  282     header("MS-ASProtocolRevisions: 12.1r1");
  283     //header("X-MS-MV: 14.0.255");
  284     // CHANGED dw2412 Support for Settings and ItemOperations command
  285     header("MS-ASProtocolCommands: Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Provision,ResolveRecipients,ValidateCert,Settings,Search,Ping,ItemOperations");
  286     header("Cache-Control: private");
  287     debugLog("POST cmd $cmd denied: Retry after sending a PROVISION command");
  288     debugLog("end");
  289     debugLog("--------");
  290     return;
  291 }
  292 
  293 // $user is usually the same as the PHP_AUTH_USER. This allows you to sync the 'john' account if you
  294 // have sufficient privileges as user 'joe'.
  295 if($backend->Setup($user, $devid, $protocolversion) == false) {
  296     header("HTTP/1.1 401 Unauthorized");
  297     header("WWW-Authenticate: Basic realm=\"ZPush\"");
  298     print("Access denied or user '$user' unknown.");
  299     debugLog("Access denied: backend setup failed.");
  300     debugLog("end");
  301     debugLog("--------");
  302     return;
  303 }
  304 
  305 // Do the actual request
  306 switch($_SERVER["REQUEST_METHOD"]) {
  307     case 'OPTIONS':
  308         // dw2412 changed to support AS14 Protocol
  309 //      Beta E2K10 ID
  310 //      header("MS-Server-ActiveSync: 14.00.048.018");
  311 //      header("MS-ASProtocolVersions: 1.0,2.0,2.1,2.5,12.0,12.1,14.0");
  312 //      header("MS-ASProtocolRevisions: 12.1r1");
  313 //      header("X-MS-MV: 14.0.255");
  314         header("MS-Server-ActiveSync: ".VERSION_SUPPORT_LAST);
  315         header("MS-ASProtocolVersions: ".VERSION_SUPPORT);
  316         
  317         /* header("MS-Server-ActiveSync: 14.1");
  318         header("MS-ASProtocolVersions: 1.0,2.0,2.1,2.5,12.0,12.1,14.0,14.1");*/
  319         // START ADDED dw2412 
  320         // Compare and send X-MS-RP depending on Protocol Version string
  321         // write the new Protocol Version string if update send
  322         include_once ('statemachine.php');
  323         $protstate = new StateMachine($devid,$user);
  324         $protsupp = $protstate->getProtocolState();
  325         if ($protsupp !== false && $protsupp != VERSION_SUPPORT) {
  326             header("X-MS-RP: ".VERSION_SUPPORT);
  327             debugLog("Sending X-MS-RP to update Protocol Version on Device");
  328             $protstate->setProtocolState(VERSION_SUPPORT);
  329         }
  330         unset($protstate);
  331         // END ADDED dw2412 
  332         // START CHANGED dw2412 Settings and ItemOperations Command Support
  333         header("MS-ASProtocolCommands: Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,ResolveRecipients,ValidateCert,Provision,Settings,Search,Ping,ItemOperations");
  334         debugLog("Options request");
  335         break;
  336     case 'POST':
  337         // dw2412 changed to support AS14 Protocol
  338         header("MS-Server-ActiveSync: ".VERSION_SUPPORT_LAST);
  339 //      header("MS-Server-ActiveSync: 14.1");
  340         debugLog("POST cmd: $cmd");
  341         // Update X-MS-RP In case version changed
  342         include_once ('statemachine.php');
  343         $protstate = new StateMachine($devid,$user);
  344         $protsupp = $protstate->getProtocolState();
  345         if ($protsupp !== false && $protsupp != VERSION_SUPPORT) {
  346             header("X-MS-RP: ".VERSION_SUPPORT);
  347             debugLog("Sending X-MS-RP to update Protocol Version on Device");
  348             $protstate->setProtocolState(VERSION_SUPPORT);
  349         }
  350         unset($protstate);
  351         // Do the actual request
  352         if(!HandleRequest($backend, $cmd, $devid, $protocolversion, $multipart)) {
  353             // Request failed. Try to output some kind of error information. We can only do this if
  354             // output had not started yet. If it has started already, we can't show the user the error, and
  355             // the device will give its own (useless) error message.
  356             if(!headers_sent()) {
  357                 header("Content-type: text/html");
  358                 print("<BODY>\n");
  359                 print("<h3>Error</h3><p>\n");
  360                 print("There was a problem processing the <i>$cmd</i> command from your PDA.\n");
  361                 print("<p>Here is the debug output:<p><pre>\n");
  362                 print(getDebugInfo());
  363                 print("</pre>\n");
  364                 print("</BODY>\n");
  365             }
  366         }
  367         break;
  368     case 'GET':
  369         header("Content-type: text/html");
  370         print("<BODY>\n");
  371         print("<h3>GET not supported</h3><p>\n");
  372         print("This is the z-push location and can only be accessed by Microsoft ActiveSync-capable devices.");
  373         print("</BODY>\n");
  374         break;
  375 }
  376 
  377 
  378 $len = ob_get_length();
  379 $data = ob_get_contents();
  380 ob_end_clean();
  381 
  382 // Unfortunately, even though zpush can stream the data to the client
  383 // with a chunked encoding, using chunked encoding also breaks the progress bar
  384 // on the PDA. So we de-chunk here and just output a content-length header and
  385 // send it as a 'normal' packet. If the output packet exceeds 1MB (see ob_start)
  386 // then it will be sent as a chunked packet anyway because PHP will have to flush
  387 // the buffer.
  388 if (!headers_sent()) { // dw2412 need to do this since i.E. getAttachmentData Request starts output in Backend...
  389     // START CHANGED dw2412 Support gzip compression in result
  390     // TODO: Find out what the hell is going on with compress DocumentLibrary body. If some needs the source
  391     //   pakets from windump, please mail me.
  392     if (GZIP_OUTPUT == true &&
  393         !defined("OVERRIDE_GZIP") &&
  394         ($gz_data = gzencode($data,9,FORCE_GZIP)) !== false) {
  395         $gzlen=strlen(bin2hex($gz_data))/2;
  396         if ($len > $gzlen) {
  397             debugLog("GZip Results: Original Size ".$len." / Compress Size ".$gzlen." byte(s) --> Send compressed data");
  398             header("Content-Encoding: gzip");
  399             header("Content-Length: ".$gzlen);
  400             flush();
  401             sleep(2);
  402             debugLog("Header Connection aborted :".(connection_aborted() ? "yes" : "no" ));
  403             debugLog("Header Connection status  :".connection_status());
  404             print $gz_data;
  405         } else {
  406             debugLog("GZip Results: Original Size ".$len." / Compress Size ".$gzlen." byte(s) --> Send uncompressed data");
  407             header("Content-Length: ".$len);
  408             flush();
  409             sleep(2);
  410             debugLog("Header Connection aborted :".(connection_aborted() ? "yes" : "no" ));
  411             debugLog("Header Connection status  :".connection_status());
  412             print $data;
  413         }
  414     } else {
  415         debugLog("Output Results: GZip not used send Original Size ".$len." byte(s) --> Send uncompressed data");
  416         header("Content-Length: ".$len);
  417         flush();
  418         sleep(2);
  419         debugLog("Header Connection aborted :".(connection_aborted() ? "yes" : "no" ));
  420         debugLog("Header Connection status  :".connection_status());
  421         print $data;
  422     }
  423     // END CHANGED dw2412 Support gzip compression in result
  424     // destruct backend after all data is on the stream
  425 } else { // just output what we maybe got from the content buffer
  426     flush();
  427     sleep(2);
  428     debugLog("1st Part Connection aborted :".(connection_aborted() ? "yes" : "no" ));
  429     debugLog("1st Part Connection status  :".connection_status());
  430     debugLog("Output ".$len." Bytes of data found in content buffer since output already started earlier in backend");
  431     print $data;
  432 }
  433 flush();
  434 sleep(2);
  435 debugLog("Session run time duration :".(microtime(true) - $sessionstarttime));
  436 debugLog("Body Connection aborted :".(connection_aborted() ? "yes" : "no" ));
  437 debugLog("Body Connection status  :".connection_status());
  438 $backend->Logoff();
  439 
  440 debugLog("end");
  441 debugLog("--------");
  442 
  443 ?>