forked from i2b2/i2b2-webclient-classic
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.php
executable file
·206 lines (161 loc) · 8.88 KB
/
index.php
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
<?php
/****************************************************************
PHP-BASED I2B2 PROXY "CELL"
(does not use SimpleXML library)
Author: Nick Benik
Last Revised: 01-27-16
*****************************************************************
This file acts as a simple i2b2 proxy cell. If no variables have been sent it is assumed that the request is from a
user's Web browser requesting the default page for the current directory. In this case, this file will read the
contents of the default.htm file and return its contents to the browser via the current HTTP connection.
New Feature: 01-27-16 (nw096):
- the $WHITELIST has been reworked to read i2b2_config_data.js and detect the hostname of where i2b2 lives
- the hostname that the web client is running on is also added to the $WHITELIST, in case i2b2 lives there
** If there are other cells/URLs that you connect to that is not where your PM Cell lives, you will need
to add that server's hostname to the $WHITELIST array below.
*/
$pmURL = "http://127.0.0.1:8080/i2b2/rest/PMService/getServices";
$pmCheckAllRequests = false;
$WHITELIST = array(
"http" . (($_SERVER['SERVER_PORT'] == '443') ? 's' : '' ) . "://" . $_SERVER['HTTP_HOST'],
"http://services.i2b2.org",
"http://127.0.0.1:9090",
"http://127.0.0.1:8080",
"http://127.0.0.1",
"http://localhost:8080",
"http://localhost:9090",
"http://localhost"
);
$BLACKLIST = array(
"http://127.0.0.1:9090/test",
"http://localhost:9090/test"
);
// There is nothing to configure below this line
$matches = array();
$config_file = fopen("i2b2_config_data.js", "r");
if($config_file){
while(($line = fgets($config_file)) !== false){
if(strpos($line, "urlCellPM:") !== false)
$matches[] = $line;
}
fclose($config_file);
}
foreach($matches as $match){
$match = preg_replace('/\s+/', '', $match); // remove all whitespace
$match = rtrim($match, ','); // remove trailing comma, if any
$regex = "/(http|https)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,5}\/?/";
if(preg_match($regex, $match, $url)) { // match hostname
array_push($WHITELIST, $url[0]);
}
}
$PostBody = file_get_contents("php://input");
if ($PostBody=="") {
// no POST variables sent, assume this is user navigation
// load the inital page "default.htm"
$IndexFile = dirname($_SERVER["SCRIPT_FILENAME"]).'/default.htm';
if (!file_exists($IndexFile) || !is_file($IndexFile)) {
die("The initial HTML file does not exist!");
} else {
// read and passthru the file contents to the browser
readfile($IndexFile);
}
} else {
// Process the POST for proxy redirection
// Validate that POST data is XML and extract <proxy> tag
$startPos = strpos($PostBody,"<redirect_url>") + 14;
$endPos = strpos($PostBody,"</redirect_url>", $startPos);
$proxyURL = substr($PostBody, $startPos, ($endPos - $startPos));
$newXML = $PostBody;
if ($pmCheckAllRequests)
{
error_log("Searhing for Security in " . $PostBody);
//Validate that user is valid against known PM
preg_match("/<security(.*)?>(.*)?<\/security>/", $PostBody, $proxySecurity);
error_log("My Security is " . $proxySecurity[1]);
preg_match("/<domain(.*)?>(.*)?<\/domain>/", $proxySecurity[0], $proxyDomain);
preg_match("/<username(.*)?>(.*)?<\/username>/", $proxySecurity[0], $proxyUsername);
preg_match("/<password(.*)?>(.*)?<\/password>/", $proxySecurity[0], $proxyPassword);
$checkPMXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><i2b2:request xmlns:i2b2=\"http://www.i2b2.org/xsd/hive/msg/1.1/\" xmlns:pm=\"http://www.i2b2.org/xsd/cell/pm/1.1/\"> <message_header> <i2b2_version_compatible>1.1</i2b2_version_compatible> <hl7_version_compatible>2.4</hl7_version_compatible> <sending_application> <application_name>i2b2 Project Management</application_name> <application_version>1.1</application_version> </sending_application> <sending_facility> <facility_name>i2b2 Hive</facility_name> </sending_facility> <receiving_application> <application_name>Project Management Cell</application_name> <application_version>1.1</application_version> </receiving_application> <receiving_facility> <facility_name>i2b2 Hive</facility_name> </receiving_facility> <datetime_of_message>2007-04-09T15:19:18.906-04:00</datetime_of_message> <security> " . $proxyDomain[0] . $proxyUsername[0] . $proxyPassword[0] . " </security> <message_control_id> <message_num>0qazI4rX6SDlQlk46wqQ3</message_num> <instance_num>0</instance_num> </message_control_id> <processing_id> <processing_id>P</processing_id> <processing_mode>I</processing_mode> </processing_id> <accept_acknowledgement_type>AL</accept_acknowledgement_type> <application_acknowledgement_type>AL</application_acknowledgement_type> <country_code>US</country_code> <project_id>undefined</project_id> </message_header> <request_header> <result_waittime_ms>180000</result_waittime_ms> </request_header> <message_body> <pm:get_user_configuration> <project>undefined</project> </pm:get_user_configuration> </message_body></i2b2:request>";
// Process the POST for proxy redirection
error_log($checkPMXML,0 );
error_log("My proxy: " . $proxyURL, 0);
}
// ---------------------------------------------------
// white-list processing on the URL
// ---------------------------------------------------
$isAllowed = false;
$requestedURL = strtoupper($proxyURL);
foreach ($WHITELIST as $entryValue) {
$checkValue = strtoupper(substr($requestedURL, 0, strlen($entryValue)));
if ($checkValue == strtoupper($entryValue)) {
$isAllowed = true;
break;
}
}
if (!$isAllowed) {
// security as failed - exit here and don't allow one more line of execution the opportunity to reverse this
die("The proxy has refused to relay your request.");
}
// ---------------------------------------------------
// black-list processing on the URL
// ---------------------------------------------------
foreach ($BLACKLIST as $entryValue) {
$checkValue = strtoupper(substr($requestedURL, 0, strlen($entryValue)));
if ($checkValue == strtoupper($entryValue)) {
// security as failed - exit here and don't allow one more line of execution the opportunity to reverse this
die("The proxy has refused to relay your request.");
}
}
if ($pmCheckAllRequests) {
// open the URL and forward the new XML in the POST body
$proxyRequest = curl_init($pmURL);
// these options are set for hyper-vigilance purposes
curl_setopt($proxyRequest, CURLOPT_COOKIESESSION, 0);
curl_setopt($proxyRequest, CURLOPT_FORBID_REUSE, 1);
curl_setopt($proxyRequest, CURLOPT_FRESH_CONNECT, 0);
// Specify NIC to use for outgoing connection, fixes firewall+DMZ headaches
// curl_setopt($proxyRequest, CURLOPT_INTERFACE, "XXX.XXX.XXX.XXX");
// other options
curl_setopt($proxyRequest, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($proxyRequest, CURLOPT_CONNECTTIMEOUT, 900); // wait 15 minutes
// data to proxy thru
curl_setopt($proxyRequest, CURLOPT_POST, 1);
curl_setopt($proxyRequest, CURLOPT_POSTFIELDS, $checkPMXML);
// SEND REQUEST!!!
curl_setopt($proxyRequest, CURLOPT_HTTPHEADER, array('Expect:', 'Content-Type: text/xml'));
$proxyResult = curl_exec($proxyRequest);
// cleanup cURL connection
curl_close($proxyRequest);
error_log("My PM Result " . $proxyResult);
$pattern = "/<status type=\"ERROR\">/i";
//Check if request is valid
if (preg_match($pattern, $proxyResult)) {
error_log("Local PM denied request");
die("Local PM server could not validate the request.");
}
}
// open the URL and forward the new XML in the POST body
$proxyRequest = curl_init($proxyURL);
curl_setopt($proxyRequest, CURLOPT_SSL_VERIFYPEER, FALSE);
// these options are set for hyper-vigilance purposes
curl_setopt($proxyRequest, CURLOPT_COOKIESESSION, 0);
curl_setopt($proxyRequest, CURLOPT_FORBID_REUSE, 1);
curl_setopt($proxyRequest, CURLOPT_FRESH_CONNECT, 0);
// Specify NIC to use for outgoing connection, fixes firewall+DMZ headaches
// curl_setopt($proxyRequest, CURLOPT_INTERFACE, "XXX.XXX.XXX.XXX");
// other options
curl_setopt($proxyRequest, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($proxyRequest, CURLOPT_CONNECTTIMEOUT, 900); // wait 15 minutes
// data to proxy thru
curl_setopt($proxyRequest, CURLOPT_POST, 1);
curl_setopt($proxyRequest, CURLOPT_POSTFIELDS, $newXML);
// SEND REQUEST!!!
curl_setopt($proxyRequest, CURLOPT_HTTPHEADER, array('Expect:', 'Content-Type: text/xml'));
$proxyResult = curl_exec($proxyRequest);
// cleanup cURL connection
curl_close($proxyRequest);
// perform any analysis or processing on the returned result here
header("Content-Type: text/xml", true);
print($proxyResult);
}
?>