server.php 6.03 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
/**
 * This program is part of Mahara
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * @package    mahara
 * @subpackage core
 * @author     Donal McMullan <donal@catalyst.net.nz>
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL
 * @copyright  (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz
 *
 */

Donal McMullan's avatar
Donal McMullan committed
27
// Errors - grep for source
28
29
30
31
32
33
34
35
36
37
38
39
// 6000     Initialization failed. Non-recoverable error.
// 6001     Payload is not a valid XML document
// 6002     Encrypted payload is not a valid XML document
// 6003     We don\'t have a record for your webserver in our database
// 6004     An error occurred while trying to verify your message signature
// 6005     The signature on your message was not valid
// 6006     The signature on your message was not valid
// 6007     Signed payload is not a valid XML document
// 6008     Payload is not an XML-RPC document
// 6009     Unrecognized XML document form
// 6010     The function does not exist
// 6011     The function does not exist
40
// 6012     Networking is disabled
41
// 6013     Networking is not available at this address. You can access this service at get_config('wwwroot')api/xmlrpc/server.php'
42

43
44
define('INTERNAL', 1);
define('PUBLIC', 1);
Donal McMullan's avatar
Donal McMullan committed
45
define('XMLRPC', 1);
46
47
48
49
50
require(dirname(__FILE__).'/lib.php');

// Catch anything that goes wrong in init.php
ob_start();
    require(dirname(dirname(dirname(__FILE__))).'/init.php');
51
    require_once(get_config('docroot') . 'api/xmlrpc/dispatcher.php');
52
53
54
    $errors = trim(ob_get_contents());
ob_end_clean();

55
56
57
// Do we respond with verbose error messages?
$networkingdebug = get_config('enablenetworkingdebug');

58
// If networking is off, return a '403 Forbidden' response
59
$networkenabled = get_config('enablenetworking');
Donal McMullan's avatar
Donal McMullan committed
60
61
62
63
$protocol = strtoupper($_SERVER['SERVER_PROTOCOL']);
if ($protocol != 'HTTP/1.1') {
    $protocol = 'HTTP/1.0';
}
64
if (empty($networkenabled)) {
65
66
67
68

    if ($networkingdebug) {
        throw new XmlrpcServerException('Networking is disabled.', 6012);
    }
69
    header($protocol.' 403 Forbidden');
70
71
72
    exit;
}

73
74
75
76
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);
}

77
// Content type for output is never html:
78
header('Content-type: text/xml; charset=utf-8');
79
ini_set('display_errors',0);
80
if (!empty($errors)) throw new XmlrpcServerException('Initialization failed. Non-recoverable error.', 6000);
81

82
83
84
85
86
87
// 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');
}

Donal McMullan's avatar
Donal McMullan committed
88
// A singleton provides our site's SSL info
89
$openssl = OpenSslRepo::singleton();
90
91
92
$payload           = $HTTP_RAW_POST_DATA;
$payload_encrypted = false;
$payload_signed    = false;
93
94
95
96
97
98
99

try {
    $xml = new SimpleXMLElement($payload);
} catch (Exception $e) {
    throw new XmlrpcServerException('Payload is not a valid XML document', 6001);
}

100
// Cascading switch. Kinda.
101
if ($xml->getName() == 'encryptedMessage') {
102
103
104
105
106
107

    // The IP address for the hostname supplied by the client.
    // This hostname can't be trusted.
    $ipaddress = gethostbyname(get_hostname_from_uri((string)$xml->wwwroot));

    // Check for masquerading
108
    if (!get_config('xmlrpc_allow_masquerading') && $ipaddress != $_SERVER['REMOTE_ADDR']) {
109
110
111
112
113
114
115
116
117
118
        if ($networkingdebug) {
            throw new XmlrpcServerException('Your hostname ('.
            get_hostname_from_uri((string)$xml->wwwroot) .
            ') resolves to the IP address '.$ipaddress .
            ' but your IP address is actually '.$_SERVER['REMOTE_ADDR'] , 6012);
        }
        header($protocol.' 403 Forbidden');
        exit;
    }

119
    $payload_encrypted = true;
120
    $REMOTEWWWROOT     = (string)$xml->wwwroot;
121
    $payload           = xmlenc_envelope_strip($xml);
122
123
}

124
if ($xml->getName() == 'signedMessage') {
125
126
127
128
129
130

    // The IP address for the hostname supplied by the client.
    // This hostname can't be trusted.
    $ipaddress = gethostbyname(get_hostname_from_uri((string)$xml->wwwroot));

    // Check for masquerading
131
    if (!get_config('xmlrpc_allow_masquerading') && $ipaddress != $_SERVER['REMOTE_ADDR']) {
132
133
134
135
136
137
138
139
140
141
        if ($networkingdebug) {
            throw new XmlrpcServerException('Your hostname ('.
            get_hostname_from_uri((string)$xml->wwwroot) .
            ') resolves to the IP address '.$ipaddress .
            ' but your IP address is actually '.$_SERVER['REMOTE_ADDR'] , 6012);
        }
        header($protocol.' 403 Forbidden');
        exit;
    }

142
    $payload_signed = true;
143
    $REMOTEWWWROOT  = (string)$xml->wwwroot;
144
    $payload        = xmldsig_envelope_strip($xml);
145
146
}

147
if ($xml->getName() == 'methodCall') {
148
    // $payload ?
149
    if (empty($xml->methodName)) {
150
151
        throw new XmlrpcServerException('Payload is not an XML-RPC document', 6008);
    }
152

153
    $Dispatcher = new Dispatcher($payload, $payload_signed, $payload_encrypted);
154
155
156
157
158
159
160
161

    if ($payload_signed) {
        $response = xmldsig_envelope($Dispatcher->response);
    } else {
        $response = $Dispatcher->response;
    }

    if ($payload_encrypted) {
162
        $peer     = get_peer($REMOTEWWWROOT);
163
164
165
166
167
        $response = xmlenc_envelope($response, $peer->certificate);
    }

    echo $response;

168
} else {
169
    throw new XmlrpcServerException('Unrecognized XML document form: ' . var_export($xml,1), 6009);
170
171
}

172
?>