source: contrib/z-push/index.php @ 4898

Revision 4898, 7.7 KB checked in by thiagoaos, 13 years ago (diff)

Ticket #2180 - Adicionado código fonte completo do zpush

Line 
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
16ob_start(false, 1048576);
17
18include_once('zpushdefs.php');
19include_once("config.php");
20include_once("proto.php");
21include_once("request.php");
22include_once("debug.php");
23include_once("compat.php");
24include_once("version.php");
25
26// Attempt to set maximum execution time
27ini_set('max_execution_time', SCRIPT_TIMEOUT);
28set_time_limit(SCRIPT_TIMEOUT);
29
30debugLog("Start");
31debugLog("Z-Push version: $zpush_version");
32debugLog("Client IP: ". $_SERVER['REMOTE_ADDR']);
33
34$input = fopen("php://input", "r");
35$output = fopen("php://output", "w+");
36
37// The script must always be called with authorisation info
38if(!isset($_SERVER['PHP_AUTH_PW'])) {
39    header("WWW-Authenticate: Basic realm=\"ZPush\"");
40    header("HTTP/1.1 401 Unauthorized");
41    print("Access denied. Please send authorisation information");
42    debugLog("Access denied: no password sent.");
43        debugLog("end");
44        debugLog("--------");
45    return;
46}
47
48// split username & domain if received as one
49$pos = strrpos($_SERVER['PHP_AUTH_USER'], '\\');
50if($pos === false){
51    $auth_user = $_SERVER['PHP_AUTH_USER'];
52    $auth_domain = '';
53}else{
54    $auth_domain = substr($_SERVER['PHP_AUTH_USER'],0,$pos);
55    $auth_user = substr($_SERVER['PHP_AUTH_USER'],$pos+1);
56}
57$auth_pw = $_SERVER['PHP_AUTH_PW'];
58
59$cmd = $user = $devid = $devtype = "";
60
61// Parse the standard GET parameters
62if(isset($_GET["Cmd"]))
63    $cmd = $_GET["Cmd"];
64if(isset($_GET["User"]))
65    $user = $_GET["User"];
66if(isset($_GET["DeviceId"]))
67    $devid = $_GET["DeviceId"];
68if(isset($_GET["DeviceType"]))
69    $devtype = $_GET["DeviceType"];
70
71// The GET parameters are required
72if($_SERVER["REQUEST_METHOD"] == "POST") {
73    if(!isset($user) || !isset($devid) || !isset($devtype)) {
74        print("Your device requested the Z-Push URL without the required GET parameters");
75        return;
76    }
77}
78
79// Get the request headers so we can see the versions
80$requestheaders = apache_request_headers();
81if (isset($requestheaders["Ms-Asprotocolversion"])) $requestheaders["MS-ASProtocolVersion"] = $requestheaders["Ms-Asprotocolversion"];
82if(isset($requestheaders["MS-ASProtocolVersion"])) {
83    global $protocolversion;
84
85    $protocolversion = $requestheaders["MS-ASProtocolVersion"];
86    debugLog("Client supports version " . $protocolversion);
87} else {
88    global $protocolversion;
89
90    $protocolversion = "1.0";
91}
92
93if (isset($requestheaders["X-Ms-Policykey"])) $requestheaders["X-MS-PolicyKey"] = $requestheaders["X-Ms-Policykey"];
94if (isset($requestheaders["X-MS-PolicyKey"])) {
95    global $policykey;
96    $policykey = $requestheaders["X-MS-PolicyKey"];
97
98} else {
99    global $policykey;
100    $policykey = 0;
101}
102
103//get user agent
104if (isset($requestheaders["User-Agent"])) {
105    global $useragent;
106    $useragent = $requestheaders["User-Agent"];
107} else {
108    global $useragent;
109    $useragent = "unknown";
110}
111
112// Load our backend driver
113$backend_dir = opendir(BASE_PATH . "/backend");
114while($entry = readdir($backend_dir)) {
115    if(substr($entry,0,1) == "." || substr($entry,-3) != "php")
116        continue;
117
118    if (!function_exists("mapi_logon") && ($entry == "ics.php"))
119        continue;
120
121    include_once(BASE_PATH . "/backend/" . $entry);
122}
123
124// Initialize our backend
125$backend = new $BACKEND_PROVIDER();
126
127if($backend->Logon($auth_user, $auth_domain, $auth_pw) == false) {
128    header("HTTP/1.1 401 Unauthorized");
129    header("WWW-Authenticate: Basic realm=\"ZPush\"");
130    print("Access denied. Username or password incorrect.");
131    debugLog("Access denied: backend logon failed.");
132    debugLog("end");
133    debugLog("--------");
134    return;
135}
136
137// $user is usually the same as the PHP_AUTH_USER. This allows you to sync the 'john' account if you
138// have sufficient privileges as user 'joe'.
139if($backend->Setup($user, $devid, $protocolversion) == false) {
140    header("HTTP/1.1 401 Unauthorized");
141    header("WWW-Authenticate: Basic realm=\"ZPush\"");
142    print("Access denied or user '$user' unknown.");
143    debugLog("Access denied: backend setup failed.");
144    debugLog("end");
145    debugLog("--------");
146    return;
147}
148
149// check policy header
150if (PROVISIONING === true && $_SERVER["REQUEST_METHOD"] != 'OPTIONS' && $cmd != 'Ping' && $cmd != 'Provision' &&
151    $backend->CheckPolicy($policykey, $devid) != SYNC_PROVISION_STATUS_SUCCESS &&
152    (LOOSE_PROVISIONING === false ||
153    (LOOSE_PROVISIONING === true && isset($requestheaders["X-MS-PolicyKey"])))) {       
154       
155    header("HTTP/1.1 449 Retry after sending a PROVISION command");
156    header("MS-Server-ActiveSync: 6.5.7638.1");
157    header("MS-ASProtocolVersions: 1.0,2.0,2.1,2.5");
158    header("MS-ASProtocolCommands: Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,Provision,ResolveRecipients,ValidateCert,Search,Ping");
159    header("Cache-Control: private");
160    debugLog("POST cmd $cmd denied: Retry after sending a PROVISION command");
161    debugLog("end");
162    debugLog("--------");
163    return;
164}
165
166// Do the actual request
167switch($_SERVER["REQUEST_METHOD"]) {
168    case 'OPTIONS':
169        header("MS-Server-ActiveSync: 6.5.7638.1");
170        header("MS-ASProtocolVersions: 1.0,2.0,2.1,2.5");
171        header("MS-ASProtocolCommands: Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstimate,MeetingResponse,ResolveRecipients,ValidateCert,Provision,Search,Ping");
172        debugLog("Options request");
173        break;
174    case 'POST':
175        header("MS-Server-ActiveSync: 6.5.7638.1");
176        debugLog("POST cmd: $cmd");
177        // Do the actual request
178        if(!HandleRequest($backend, $cmd, $devid, $protocolversion)) {
179            // Request failed. Try to output some kind of error information. We can only do this if
180            // output had not started yet. If it has started already, we can't show the user the error, and
181            // the device will give its own (useless) error message.
182            if(!headers_sent()) {
183                header("Content-type: text/html");
184                print("<BODY>\n");
185                print("<h3>Error</h3><p>\n");
186                print("There was a problem processing the <i>$cmd</i> command from your PDA.\n");
187                print("<p>Here is the debug output:<p><pre>\n");
188                print(getDebugInfo());
189                print("</pre>\n");
190                print("</BODY>\n");
191            }
192        }
193        break;
194    case 'GET':
195        header("Content-type: text/html");
196        print("<BODY>\n");
197        print("<h3>GET not supported</h3><p>\n");
198        print("This is the z-push location and can only be accessed by Microsoft ActiveSync-capable devices.");
199        print("</BODY>\n");
200        break;
201}
202
203
204$len = ob_get_length();
205$data = ob_get_contents();
206
207ob_end_clean();
208
209// Unfortunately, even though zpush can stream the data to the client
210// with a chunked encoding, using chunked encoding also breaks the progress bar
211// on the PDA. So we de-chunk here and just output a content-length header and
212// send it as a 'normal' packet. If the output packet exceeds 1MB (see ob_start)
213// then it will be sent as a chunked packet anyway because PHP will have to flush
214// the buffer.
215
216header("Content-Length: $len");
217print $data;
218
219// destruct backend after all data is on the stream
220$backend->Logoff();
221
222debugLog("end");
223debugLog("--------");
224?>
Note: See TracBrowser for help on using the repository browser.