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 |
5beb7c53 AA |
67 | // 'progressbar's never change, attempt an IMS shortcut before loading init.php |
68 | if (@$_REQUEST['img'] == 'progressbar') | |
8b912171 | 69 | if (checkCachedResponse (0, CACHE_DURATION)) |
5beb7c53 | 70 | exit; |
5c42f907 | 71 | require_once 'inc/solutions.php'; |
4afb4c10 DO |
72 | try |
73 | { | |
74 | dispatchImageRequest(); | |
75 | } | |
3ec33017 DO |
76 | catch (RTPermissionDenied $e) |
77 | { | |
78 | ob_clean(); | |
79 | renderAccessDeniedImage(); | |
80 | } | |
4afb4c10 DO |
81 | catch (Exception $e) |
82 | { | |
87c744a9 | 83 | ob_clean(); |
11566bd6 | 84 | renderErrorImage(); |
4afb4c10 DO |
85 | } |
86 | break; | |
c5dfde62 | 87 | case 'ajax' == $_REQUEST['module']: |
9f4f431c DO |
88 | require_once 'inc/ajax-interface.php'; |
89 | require_once 'inc/init.php'; | |
90 | try | |
91 | { | |
92 | dispatchAJAXRequest(); | |
93 | } | |
94 | catch (InvalidRequestArgException $e) | |
95 | { | |
96 | ob_clean(); | |
97 | echo "NAK\nMalformed request"; | |
98 | } | |
99 | catch (Exception $e) | |
100 | { | |
101 | ob_clean(); | |
102 | echo "NAK\nRuntime exception: ". $e->getMessage(); | |
103 | } | |
104 | break; | |
c5dfde62 | 105 | case 'redirect' == $_REQUEST['module']: |
87c744a9 DO |
106 | // Include init after ophandlers/snmp, not before, so local.php can redefine things. |
107 | require_once 'inc/ophandlers.php'; | |
108 | // snmp.php is an exception, it is treated by a special hack | |
109 | if (isset ($_REQUEST['op']) and $_REQUEST['op'] == 'querySNMPData') | |
110 | require_once 'inc/snmp.php'; | |
111 | require_once 'inc/init.php'; | |
112 | try | |
113 | { | |
114 | genericAssertion ('op', 'string'); | |
115 | $op = $_REQUEST['op']; | |
116 | prepareNavigation(); | |
117 | $location = buildWideRedirectURL(); | |
118 | // FIXME: find a better way to handle this error | |
119 | if ($op == 'addFile' && !isset($_FILES['file']['error'])) | |
120 | throw new RackTablesError ('File upload error, check upload_max_filesize in php.ini', RackTablesError::MISCONFIGURED); | |
121 | fixContext(); | |
122 | if | |
123 | ( | |
124 | !isset ($ophandler[$pageno][$tabno][$op]) or | |
125 | !function_exists ($ophandler[$pageno][$tabno][$op]) | |
126 | ) | |
127 | throw new RackTablesError ("Invalid navigation data for '${pageno}-${tabno}-${op}'", RackTablesError::INTERNAL); | |
128 | // We have a chance to handle an error before starting HTTP header. | |
3ec33017 DO |
129 | if (!isset ($delayauth[$pageno][$tabno][$op])) |
130 | assertPermission(); | |
131 | # Call below does the job of bypass argument assertion, if such is required, | |
132 | # so the ophandler function doesn't have to re-assert this portion of its | |
133 | # arguments. And it would be even better to pass returned value to ophandler, | |
134 | # so it is not necessary to remember the name of bypass in it. | |
135 | getBypassValue(); | |
136 | if (strlen ($redirect_to = call_user_func ($ophandler[$pageno][$tabno][$op]))) | |
137 | $location = $redirect_to; | |
87c744a9 DO |
138 | } |
139 | // known "soft" failures require a short error message | |
93c946ac | 140 | catch (InvalidRequestArgException $e) |
87c744a9 DO |
141 | { |
142 | ob_clean(); | |
143 | showError ($e->getMessage()); | |
87c744a9 DO |
144 | } |
145 | catch (RTDatabaseError $e) | |
146 | { | |
147 | ob_clean(); | |
148 | showError ('Database error: ' . $e->getMessage()); | |
87c744a9 | 149 | } |
3ec33017 DO |
150 | catch (RTPermissionDenied $e) |
151 | { | |
152 | ob_clean(); | |
153 | showError ('Operation not permitted'); | |
154 | } | |
155 | header ('Location: ' . $location); | |
87c744a9 DO |
156 | // any other error requires no special handling and will be caught outside |
157 | break; | |
e0ce8064 DO |
158 | case 'popup' == $_REQUEST['module']: |
159 | require_once 'inc/popup.php'; | |
e0ce8064 DO |
160 | require_once 'inc/init.php'; |
161 | renderPopupHTML(); | |
162 | break; | |
964b0388 DO |
163 | case 'upgrade' == $_REQUEST['module']: |
164 | require_once 'inc/config.php'; // for CODE_VERSION | |
165 | require_once 'inc/dictionary.php'; | |
166 | require_once 'inc/upgrade.php'; | |
167 | // Enforce default value for now, releases prior to 0.17.0 didn't support 'httpd' auth source. | |
168 | $user_auth_src = 'database'; | |
169 | if (FALSE === @include_once 'inc/secret.php') | |
e37cfe5f | 170 | die ('<center>There is no working RackTables instance here, <a href="?module=installer">install</a>?</center>'); |
964b0388 DO |
171 | try |
172 | { | |
173 | $dbxlink = new PDO ($pdo_dsn, $db_username, $db_password); | |
174 | } | |
175 | catch (PDOException $e) | |
176 | { | |
177 | die ("Database connection failed:\n\n" . $e->getMessage()); | |
178 | } | |
179 | renderUpgraderHTML(); | |
180 | break; | |
91bd1d6e | 181 | case 'installer' == $_REQUEST['module']: |
e37cfe5f DO |
182 | require_once 'inc/dictionary.php'; |
183 | require_once 'inc/install.php'; | |
184 | renderInstallerHTML(); | |
185 | break; | |
36ef72d9 DO |
186 | default: |
187 | throw new InvalidRequestArgException ('module', $_REQUEST['module']); | |
188 | } | |
0415b520 | 189 | ob_end_flush(); |
36ef72d9 | 190 | } |
c5dfde62 DO |
191 | catch (Exception $e) |
192 | { | |
90a3d6d8 | 193 | ob_end_clean(); |
91bd1d6e DO |
194 | # prevent message appearing in foreign tab |
195 | if (isset ($_SESSION['log'])) | |
196 | unset ($_SESSION['log']); | |
c5dfde62 | 197 | printException ($e); |
90a3d6d8 | 198 | } |
e410ebfc | 199 | ?> |