1+ <?php
2+ include ("../../lib/settings.php " );
3+ if ($ demoMode || !$ _SESSION ['loggedIn ' ]) {
4+ die ("You must be logged in to access Terminal " );
5+ }
6+
7+ error_reporting (E_ALL );
8+ @session_start ();
9+
10+ if (isset ($ _SERVER ['PHP_AUTH_USER ' ])) {
11+ $ _SESSION ['user ' ] = $ _SERVER ['PHP_AUTH_USER ' ];
12+ $ _SESSION ['pass ' ] = $ _SERVER ['PHP_AUTH_PW ' ];
13+ }
14+ $ passwd = array ($ _SESSION ['user ' ] => $ _SESSION ['pass ' ]);
15+ $ aliases = array ('la ' => 'ls -la ' ,
16+ 'll ' => 'ls -lvhF ' ,
17+ 'dir ' => 'ls ' );
18+
19+ class phpTerm {
20+ function phpTerm () {} // constructor
21+
22+ function formatPrompt () {
23+ $ user =shell_exec ("whoami " );
24+ $ host =explode (". " , shell_exec ("uname -n " ));
25+ $ _SESSION ['prompt ' ] = "" .rtrim ($ user )."" ."@ " ."" .rtrim ($ host [0 ])."" ;
26+ }
27+
28+ function checkPassword ($ passwd ) {
29+ if ( !isset ($ _SERVER ['PHP_AUTH_USER ' ])||
30+ !isset ($ _SERVER ['PHP_AUTH_PW ' ]) ||
31+ !isset ($ passwd [$ _SERVER ['PHP_AUTH_USER ' ]]) ||
32+ $ passwd [$ _SERVER ['PHP_AUTH_USER ' ]] != $ _SERVER ['PHP_AUTH_PW ' ]) {
33+ return false ;
34+ } else {
35+ return true ;
36+ }
37+ }
38+
39+ function logout () {
40+ header ('WWW-Authenticate: Basic realm="Terminal" ' );
41+ header ('HTTP/1.0 401 Unauthorized ' );
42+ exit ();
43+ }
44+
45+ function initVars () {
46+ if (empty ($ _SESSION ['cwd ' ]) || @!empty ($ _GET ['reset ' ])) {
47+ $ _SESSION ['cwd ' ] = getcwd ();
48+ $ _SESSION ['history ' ] = array ();
49+ $ _SESSION ['output ' ] = '' ;
50+ $ _REQUEST ['command ' ] ='' ;
51+ }
52+ }
53+
54+ function buildCommandHistory () {
55+ if (!empty ($ _REQUEST ['command ' ])) {
56+ if (get_magic_quotes_gpc ()) {
57+ $ _REQUEST ['command ' ] = stripslashes ($ _REQUEST ['command ' ]);
58+ }
59+
60+ // drop old commands from list if exists
61+ if (($ i = array_search ($ _REQUEST ['command ' ], $ _SESSION ['history ' ])) !== false ) {
62+ unset($ _SESSION ['history ' ][$ i ]);
63+ }
64+ array_unshift ($ _SESSION ['history ' ], $ _REQUEST ['command ' ]);
65+
66+ // append commmand */
67+ $ _SESSION ['output ' ] .= "{$ _SESSION ['prompt ' ]}" .":> " ."{$ _REQUEST ['command ' ]}" ."\n" ;
68+ }
69+ }
70+
71+ function buildJavaHistory () {
72+ // build command history for use in the JavaScript
73+ if (empty ($ _SESSION ['history ' ])) {
74+ $ _SESSION ['js_command_hist ' ] = '"" ' ;
75+ } else {
76+ $ escaped = array_map ('addslashes ' , $ _SESSION ['history ' ]);
77+ $ _SESSION ['js_command_hist ' ] = '"", " ' . implode ('", " ' , $ escaped ) . '" ' ;
78+ }
79+ }
80+
81+ function outputHandle ($ aliases ) {
82+ if (preg_match ('/^[[:blank:]]*cd[[:blank:]]*$/ ' , @$ _REQUEST ['command ' ]))
83+ {
84+ $ _SESSION ['cwd ' ] = getcwd (); //dirname(__FILE__);
85+ }
86+ elseif (preg_match ('/^[[:blank:]]*cd[[:blank:]]+([^;]+)$/ ' , @$ _REQUEST ['command ' ], $ regs )) {
87+ // The current command is 'cd', which we have to handle as an internal shell command.
88+ // absolute/relative path ?"
89+ ($ regs [1 ][0 ] == '/ ' ) ? $ new_dir = $ regs [1 ] : $ new_dir = $ _SESSION ['cwd ' ] . '/ ' . $ regs [1 ];
90+
91+ // cosmetics
92+ while (strpos ($ new_dir , '/./ ' ) !== false ) {
93+ $ new_dir = str_replace ('/./ ' , '/ ' , $ new_dir );
94+ }
95+ while (strpos ($ new_dir , '// ' ) !== false ) {
96+ $ new_dir = str_replace ('// ' , '/ ' , $ new_dir );
97+ }
98+ while (preg_match ('|/\.\.(?!\.)| ' , $ new_dir )) {
99+ $ new_dir = preg_replace ('|/?[^/]+/\.\.(?!\.)| ' , '' , $ new_dir );
100+ }
101+
102+ if (empty ($ new_dir )): $ new_dir = "/ " ; endif ;
103+
104+ (@chdir ($ new_dir )) ? $ _SESSION ['cwd ' ] = $ new_dir : $ _SESSION ['output ' ] .= "could not change to: $ new_dir \n" ;
105+ } else {
106+ /* The command is not a 'cd' command, so we execute it after
107+ changing the directory and save the output. */
108+ chdir ($ _SESSION ['cwd ' ]);
109+
110+ /* Alias expansion. */
111+ $ length = strcspn (@$ _REQUEST ['command ' ], " \t" );
112+ $ token = substr (@$ _REQUEST ['command ' ], 0 , $ length );
113+ if (isset ($ aliases [$ token ]))
114+ $ _REQUEST ['command ' ] = $ aliases [$ token ] . substr ($ _REQUEST ['command ' ], $ length );
115+
116+ $ p = proc_open (@$ _REQUEST ['command ' ],
117+ array (1 => array ('pipe ' , 'w ' ),
118+ 2 => array ('pipe ' , 'w ' )), $ io );
119+
120+ /* Read output sent to stdout. */
121+ while (!feof ($ io [1 ])) {
122+ $ _SESSION ['output ' ] .= htmlspecialchars (fgets ($ io [1 ]),ENT_COMPAT , 'UTF-8 ' );
123+ }
124+ /* Read output sent to stderr. */
125+ while (!feof ($ io [2 ])) {
126+ $ _SESSION ['output ' ] .= htmlspecialchars (fgets ($ io [2 ]),ENT_COMPAT , 'UTF-8 ' );
127+ }
128+
129+ fclose ($ io [1 ]);
130+ fclose ($ io [2 ]);
131+ proc_close ($ p );
132+ }
133+ }
134+ }
135+
136+ $ terminal = new phpTerm ;
137+
138+ if ($ _REQUEST ['command ' ]=="logout " ) {
139+ $ terminal ->logout ();
140+ }
141+
142+ if (!$ terminal ->checkPassword ($ passwd )) {
143+ header ('WWW-Authenticate: Basic realm="Terminal" ' );
144+ header ('HTTP/1.0 401 Unauthorized ' );
145+ } else {
146+ $ terminal ->initVars ();
147+ $ terminal ->buildCommandHistory ();
148+ $ terminal ->buildJavaHistory ();
149+ if (!isset ($ _SESSION ['prompt ' ])):$ terminal ->formatPrompt (); endif ;
150+ $ terminal ->outputHandle ($ aliases );
151+ ?>
152+ <!DOCTYPE html>
153+ <html lang="en">
154+ <head>
155+ <title>PHP Terminal</title>
156+ <link rel="stylesheet" type="text/css" href="terminal.css" />
157+ <script type="text/javascript" language="JavaScript">
158+ var current_line = 0;
159+ var command_hist = new Array(<?php echo $ _SESSION ['js_command_hist ' ]; ?> );
160+ var last = 0;
161+
162+ function key(e) {
163+ if (!e) var e = window.event;
164+ if (e.keyCode == 38 && current_line < command_hist.length-1) {
165+ command_hist[current_line] = document.shell.command.value;
166+ current_line++;
167+ document.shell.command.value = command_hist[current_line];
168+ }
169+ if (e.keyCode == 40 && current_line > 0) {
170+ command_hist[current_line] = document.shell.command.value;
171+ current_line--;
172+ document.shell.command.value = command_hist[current_line];
173+ }
174+ }
175+
176+ function init() {
177+ document.shell.setAttribute("autocomplete", "off");
178+ document.shell.output.scrollTop = document.shell.output.scrollHeight;
179+ document.shell.command.focus();
180+ }
181+
182+ </script>
183+ </head>
184+
185+ <body onload="init()">
186+
187+ <div class="head"><?php echo $ _SESSION ['prompt ' ].": " ."$ _SESSION [cwd]" ; ?> </div>
188+
189+ <form name="shell" action="<?php echo $ _SERVER ['PHP_SELF ' ];?> " method="post">
190+ <textarea name="output" readonly="readonly" rows="24"><?php
191+ $ lines = substr_count ($ _SESSION ['output ' ], "\n" );
192+ $ padding = str_repeat ("\n" , max (0 , 25 - $ lines ));
193+ echo "\n\n" .trim ($ padding . $ _SESSION ['output ' ])."\n" ;
194+ ?>
195+ </textarea>
196+ <p class="commandLine">$> <input class="command" name="command" type="text" size='50' onkeyup="key(event)" tabindex="1"></p>
197+ </form>
198+
199+ </body>
200+ </html>
201+ <?php } ?>
0 commit comments