Commit | Line | Data |
---|---|---|
b325120a | 1 | <?php |
90a3d6d8 | 2 | ob_start(); |
91bd1d6e DO |
3 | # Neither "throw/catch" for custom exceptions nor printException() will |
4 | # work without first loading exceptions.php. | |
5 | require_once 'inc/exceptions.php'; | |
90a3d6d8 | 6 | try { |
87c744a9 DO |
7 | // Code block below is a module request dispatcher. Turning it into a |
8 | // function will break things because of the way require() works. | |
c5dfde62 | 9 | switch (TRUE) |
36ef72d9 | 10 | { |
c5dfde62 DO |
11 | case ! array_key_exists ('module', $_REQUEST): |
12 | case 'interface' == $_REQUEST['module']: | |
13 | require_once 'inc/interface.php'; | |
14 | // init.php has to be included after interface.php, otherwise the bits | |
15 | // set by local.php get lost | |
16 | require_once 'inc/init.php'; | |
17 | prepareNavigation(); | |
18 | // Security context is built on the requested page/tab/bypass data, | |
19 | // do not override. | |
20 | fixContext(); | |
21 | redirectIfNecessary(); | |
3ec33017 | 22 | assertPermission(); |
c5dfde62 DO |
23 | header ('Content-Type: text/html; charset=UTF-8'); |
24 | // Only store the tab name after clearance is got. Any failure is unhandleable. | |
25 | if (isset ($_REQUEST['tab']) and ! isset ($_SESSION['RTLT'][$pageno]['dont_remember'])) | |
26 | $_SESSION['RTLT'][$pageno] = array ('tabname' => $tabno, 'time' => time()); | |
27 | // call the main handler - page or tab handler. | |
28 | if (isset ($tabhandler[$pageno][$tabno])) | |
29 | call_user_func ($tabhandler[$pageno][$tabno], getBypassValue()); | |
30 | elseif (isset ($page[$pageno]['handler'])) | |
31 | $page[$pageno]['handler'] ($tabno); | |
32 | else | |
33 | throw new RackTablesError ("Failed to find handler for page '${pageno}', tab '${tabno}'", RackTablesError::INTERNAL); | |
34 | // Embed the current text in OB into interface layout (the latter also | |
35 | // empties color message buffer). | |
36 | $contents = ob_get_contents(); | |
37 | ob_clean(); | |
38 | renderInterfaceHTML ($pageno, $tabno, $contents); | |
39 | break; | |
19f22ad8 | 40 | case 'chrome' == $_REQUEST['module']: |
4afb4c10 | 41 | require_once 'inc/init.php'; |
5c42f907 | 42 | require_once 'inc/solutions.php'; |
36ef72d9 DO |
43 | genericAssertion ('uri', 'string'); |
44 | proxyStaticURI ($_REQUEST['uri']); | |
45 | break; | |
c5dfde62 | 46 | case 'download' == $_REQUEST['module']: |
4afb4c10 | 47 | require_once 'inc/init.php'; |
0415b520 DO |
48 | $pageno = 'file'; |
49 | $tabno = 'download'; | |
50 | fixContext(); | |
3ec33017 | 51 | assertPermission(); |
0415b520 DO |
52 | $file = getFile (getBypassValue()); |
53 | header("Content-Type: {$file['type']}"); | |
54 | header("Content-Length: {$file['size']}"); | |
39cfa9a7 | 55 | if (! array_key_exists ('asattach', $_REQUEST) or $_REQUEST['asattach'] != 'no') |
0415b520 DO |
56 | header("Content-Disposition: attachment; filename={$file['name']}"); |
57 | echo $file['contents']; | |
58 | break; | |
c5dfde62 | 59 | case 'image' == $_REQUEST['module']: |
b849b7e1 DO |
60 | # The difference between "image" and "download" ways to serve the same |
61 | # picture file is that the former is used in <IMG SRC=...> construct, | |
62 | # and the latter is accessed as a standalone URL and can reply with any | |
63 | # Content-type. Hence "image" module indicates failures with internally | |
64 | # built images, and "download" can return a full-fledged "permission | |
65 | # denied" or "exception" HTML page instead of the file requested. | |
8b912171 | 66 | require_once 'inc/init.php'; // for authentication check |
5c42f907 | 67 | require_once 'inc/solutions.php'; |
4afb4c10 DO |
68 | try |
69 | { | |
70 | dispatchImageRequest(); | |
71 | } | |
3ec33017 DO |
72 | catch (RTPermissionDenied $e) |
73 | { | |
74 | ob_clean(); | |
75 | renderAccessDeniedImage(); | |
76 | } | |
4afb4c10 DO |
77 | catch (Exception $e) |
78 | { | |
87c744a9 | 79 | ob_clean(); |
11566bd6 | 80 | renderErrorImage(); |
4afb4c10 DO |
81 | } |
82 | break; | |
a069b30d DO |
83 | case 'progressbar' == $_REQUEST['module']: |
84 | # Unlike images (and like static content), progress bars are processed | |
85 | # without a permission check, but only for authenticated users. | |
86 | require_once 'inc/init.php'; | |
87 | require_once 'inc/solutions.php'; | |
88 | genericAssertion ('done', 'uint0'); | |
89 | // 'progressbar's never change, make browser cache the result | |
90 | if (checkCachedResponse (0, CACHE_DURATION)) | |
91 | break; | |
92 | renderProgressBarImage ($_REQUEST['done']); | |
93 | break; | |
c5dfde62 | 94 | case 'ajax' == $_REQUEST['module']: |
9f4f431c DO |
95 | require_once 'inc/ajax-interface.php'; |
96 | require_once 'inc/init.php'; | |
97 | try | |
98 | { | |
99 | dispatchAJAXRequest(); | |
100 | } | |
101 | catch (InvalidRequestArgException $e) | |
102 | { | |
103 | ob_clean(); | |
104 | echo "NAK\nMalformed request"; | |
105 | } | |
fce31eff DO |
106 | catch (RTPermissionDenied $e) |
107 | { | |
108 | ob_clean(); | |
109 | # FIXME: the remote client could be expecting JSON data instead | |
110 | echo "NAK\nPermission denied"; | |
111 | } | |
9f4f431c DO |
112 | catch (Exception $e) |
113 | { | |
114 | ob_clean(); | |
115 | echo "NAK\nRuntime exception: ". $e->getMessage(); | |
116 | } | |
117 | break; | |
c5dfde62 | 118 | case 'redirect' == $_REQUEST['module']: |
87c744a9 DO |
119 | // Include init after ophandlers/snmp, not before, so local.php can redefine things. |
120 | require_once 'inc/ophandlers.php'; | |
121 | // snmp.php is an exception, it is treated by a special hack | |
122 | if (isset ($_REQUEST['op']) and $_REQUEST['op'] == 'querySNMPData') | |
123 | require_once 'inc/snmp.php'; | |
124 | require_once 'inc/init.php'; | |
125 | try | |
126 | { | |
127 | genericAssertion ('op', 'string'); | |
128 | $op = $_REQUEST['op']; | |
129 | prepareNavigation(); | |
130 | $location = buildWideRedirectURL(); | |
131 | // FIXME: find a better way to handle this error | |
132 | if ($op == 'addFile' && !isset($_FILES['file']['error'])) | |
133 | throw new RackTablesError ('File upload error, check upload_max_filesize in php.ini', RackTablesError::MISCONFIGURED); | |
134 | fixContext(); | |
135 | if | |
136 | ( | |
137 | !isset ($ophandler[$pageno][$tabno][$op]) or | |
138 | !function_exists ($ophandler[$pageno][$tabno][$op]) | |
139 | ) | |
140 | throw new RackTablesError ("Invalid navigation data for '${pageno}-${tabno}-${op}'", RackTablesError::INTERNAL); | |
141 | // We have a chance to handle an error before starting HTTP header. | |
3ec33017 DO |
142 | if (!isset ($delayauth[$pageno][$tabno][$op])) |
143 | assertPermission(); | |
144 | # Call below does the job of bypass argument assertion, if such is required, | |
145 | # so the ophandler function doesn't have to re-assert this portion of its | |
146 | # arguments. And it would be even better to pass returned value to ophandler, | |
147 | # so it is not necessary to remember the name of bypass in it. | |
148 | getBypassValue(); | |
149 | if (strlen ($redirect_to = call_user_func ($ophandler[$pageno][$tabno][$op]))) | |
150 | $location = $redirect_to; | |
87c744a9 DO |
151 | } |
152 | // known "soft" failures require a short error message | |
93c946ac | 153 | catch (InvalidRequestArgException $e) |
87c744a9 DO |
154 | { |
155 | ob_clean(); | |
156 | showError ($e->getMessage()); | |
87c744a9 DO |
157 | } |
158 | catch (RTDatabaseError $e) | |
159 | { | |
160 | ob_clean(); | |
161 | showError ('Database error: ' . $e->getMessage()); | |
87c744a9 | 162 | } |
3ec33017 DO |
163 | catch (RTPermissionDenied $e) |
164 | { | |
165 | ob_clean(); | |
166 | showError ('Operation not permitted'); | |
167 | } | |
168 | header ('Location: ' . $location); | |
87c744a9 DO |
169 | // any other error requires no special handling and will be caught outside |
170 | break; | |
e0ce8064 DO |
171 | case 'popup' == $_REQUEST['module']: |
172 | require_once 'inc/popup.php'; | |
e0ce8064 DO |
173 | require_once 'inc/init.php'; |
174 | renderPopupHTML(); | |
175 | break; | |
964b0388 DO |
176 | case 'upgrade' == $_REQUEST['module']: |
177 | require_once 'inc/config.php'; // for CODE_VERSION | |
178 | require_once 'inc/dictionary.php'; | |
179 | require_once 'inc/upgrade.php'; | |
180 | // Enforce default value for now, releases prior to 0.17.0 didn't support 'httpd' auth source. | |
181 | $user_auth_src = 'database'; | |
182 | if (FALSE === @include_once 'inc/secret.php') | |
e37cfe5f | 183 | die ('<center>There is no working RackTables instance here, <a href="?module=installer">install</a>?</center>'); |
964b0388 DO |
184 | try |
185 | { | |
186 | $dbxlink = new PDO ($pdo_dsn, $db_username, $db_password); | |
187 | } | |
188 | catch (PDOException $e) | |
189 | { | |
190 | die ("Database connection failed:\n\n" . $e->getMessage()); | |
191 | } | |
192 | renderUpgraderHTML(); | |
193 | break; | |
91bd1d6e | 194 | case 'installer' == $_REQUEST['module']: |
e37cfe5f DO |
195 | require_once 'inc/dictionary.php'; |
196 | require_once 'inc/install.php'; | |
197 | renderInstallerHTML(); | |
198 | break; | |
36ef72d9 DO |
199 | default: |
200 | throw new InvalidRequestArgException ('module', $_REQUEST['module']); | |
201 | } | |
0415b520 | 202 | ob_end_flush(); |
36ef72d9 | 203 | } |
c5dfde62 DO |
204 | catch (Exception $e) |
205 | { | |
90a3d6d8 | 206 | ob_end_clean(); |
91bd1d6e DO |
207 | # prevent message appearing in foreign tab |
208 | if (isset ($_SESSION['log'])) | |
209 | unset ($_SESSION['log']); | |
c5dfde62 | 210 | printException ($e); |
90a3d6d8 | 211 | } |
e410ebfc | 212 | ?> |