Project

General

Profile

Download (10.2 KB) Statistics
| Branch: | Tag: | Revision:
1
#!/usr/local/bin/php-cgi -f
2
<?php
3
/*
4
 * pfSsh
5
 *
6
 * part of pfSense (https://www.pfsense.org)
7
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
8
 * All rights reserved.
9
 *
10
 * Licensed under the Apache License, Version 2.0 (the "License");
11
 * you may not use this file except in compliance with the License.
12
 * You may obtain a copy of the License at
13
 *
14
 * http://www.apache.org/licenses/LICENSE-2.0
15
 *
16
 * Unless required by applicable law or agreed to in writing, software
17
 * distributed under the License is distributed on an "AS IS" BASIS,
18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
 * See the License for the specific language governing permissions and
20
 * limitations under the License.
21
 */
22

    
23
require_once("globals.inc");
24
if ($argc < 2) {
25
	echo "Starting the {$g['product_name']} developer shell";
26
}
27
require_once("functions.inc");
28
if ($argc < 2) {
29
	echo ".";
30
}
31
require_once("config.inc");
32
if ($argc < 2) {
33
	echo ".";
34
}
35
require_once("util.inc");
36
if ($argc < 2) {
37
	echo ".";
38
}
39

    
40
$shell_cmds = array("alias", "alloc", "bg", "bind", "bindkey", "break",
41
	 "breaksw", "builtins", "case", "cd", "chdir", "command", "complete", "continue", "default",
42
	 "dirs", "do", "done", "echo", "echotc", "elif", "else", "end", "endif", "endsw", "esac", "eval",
43
	 "exec", "exit", "export", "false", "fc", "fg", "filetest", "fi", "for", "foreach", "getopts",
44
	 "glob", "goto", "hash", "hashstat", "history", "hup", "if", "jobid", "jobs", "kill", "limit",
45
	 "local", "log", "login", "logout", "ls-F", "nice", "nohup", "notify", "onintr", "popd",
46
	 "printenv", "pushd", "pwd", "read", "readonly", "rehash", "repeat", "return", "sched", "set",
47
	 "setenv", "settc", "setty", "setvar", "shift", "source", "stop", "suspend", "switch",
48
	 "telltc", "test", "then", "time", "trap", "true", "type", "ulimit", "umask", "unalias",
49
	 "uncomplete", "unhash", "unlimit", "unset", "unsetenv", "until", "wait", "where", "which",
50
	 "while");
51

    
52
function pipe_cmd($command, $text_to_pipe) {
53
	$descriptorspec = array(
54
		0 => array("pipe", "r"),  // stdin
55
		1 => array("pipe", "w"),  // stdout
56
		2 => array("pipe", "w")); // stderr ?? instead of a file
57

    
58
	$fd = proc_open("$command", $descriptorspec, $pipes);
59
	if (is_resource($fd)) {
60
		fwrite($pipes[0], "{$text_to_pipe}");
61
		fclose($pipes[0]);
62
		while ($s= fgets($pipes[1], 1024)) {
63
			// read from the pipe
64
			$buffer .= $s;
65
		}
66
		fclose($pipes[1]);
67
		fclose($pipes[2]);
68
	}
69
	return $buffer;
70
}
71

    
72
if (!function_exists("readline")) {
73
	function readline() {
74
		$fp = fopen('php://stdin', 'r');
75
		$textinput = chop(fgets($fp));
76
		fclose($fp);
77
		return $textinput;
78
	}
79
}
80

    
81
function more($text, $count=24) {
82
	$counter=0;
83
	$lines = explode("\n", $text);
84
	foreach ($lines as $line) {
85
		if ($counter > $count) {
86
			echo "Press RETURN to continue ...";
87
			$fp = fopen('php://stdin', 'r');
88
			$pressreturn = chop(fgets($fp));
89
			if ($pressreturn == "q" || $pressreturn == "quit") {
90
				return;
91
			}
92
			fclose($fp);
93
			$counter = 0;
94
		}
95
		echo "{$line}\n";
96
		$counter++;
97
	}
98
}
99

    
100
function show_help() {
101

    
102
$show_help_text = <<<EOF
103

    
104
	Enter a series of commands and then execute the set with "exec".
105

    
106
	For example:
107
	echo "foo"; // php command
108
	echo "foo2"; // php command
109
	! echo "heh" # shell command
110
	exec
111

    
112
	Example commands:
113

    
114
	record <recordingfilename>
115
	stoprecording
116
	showrecordings
117

    
118
	parse_config(true);  # reloads the \$config array
119

    
120
	\$temp = print_r(\$config, true);
121
	more(\$temp);
122

    
123
	/* to output a configuration array */
124
	print_r(\$config);
125

    
126
	/* to output the interfaces configuration portion of config.xml */
127
	print_r(\$config['interfaces']);
128

    
129
	/* to output the dhcp server configuration */
130
	print_r(\$config['dhcpd']);
131

    
132
	/* to exit the {$g['product_name']} developer shell */
133
	exit
134

    
135
	/* to output supported wireless modes for an interface */
136
	print_r(get_wireless_modes(\"ath0\"));
137

    
138
	/* to enable SSH */
139
	\$config['system']['enablesshd'] = true;
140

    
141
	/* change OPTX to the OPT interface name such as BACKHAUL */
142
	\$config['interfaces']['optx']['wireless']['standard'] = "11a";
143
	\$config['interfaces']['optx']['wireless']['mode'] = "hostap";
144
	\$config['interfaces']['optx']['wireless']['channel'] = "6";
145

    
146
	/* to enable dhcp server for an optx interface */
147
	\$config['dhcpd']['optx']['enable'] = true;
148
	\$config['dhcpd']['optx']['range']['from'] = "192.168.31.100";
149
	\$config['dhcpd']['optx']['range']['to'] = "192.168.31.150";
150

    
151
	/* to disable the firewall filter */
152
	\$config['system']['disablefilter'] = true;
153

    
154
	/* to enable an interface and configure it as a DHCP client */
155
	\$config['interfaces']['optx']['disabled'] = false;
156
	\$config['interfaces']['optx']['ipaddr'] = "dhcp";
157

    
158
	/* to enable an interface and set a static IPv4 address */
159
	\$config['interfaces']['wan']['enable'] = true;
160
	\$config['interfaces']['wan']['ipaddr'] = "192.168.100.1";
161
	\$config['interfaces']['wan']['subnet'] = "24";
162

    
163
	/* to save out the new configuration (config.xml) */
164
	write_config();
165

    
166
	/* to reboot the system after saving */
167
	system_reboot_sync();
168

    
169
EOF;
170

    
171
	more($show_help_text);
172

    
173
}
174

    
175
$fp = fopen('php://stdin', 'r');
176

    
177
if ($argc < 2) {
178
	echo ".\n\n";
179
}
180

    
181
$pkg_interface='console';
182

    
183
$shell_active = true;
184
$tccommands = array();
185

    
186
function completion($string, $index) {
187
	global $tccommands;
188
	return $tccommands;
189
}
190

    
191
readline_completion_function("completion");
192

    
193
function get_playback_files() {
194
	$playback_files = array();
195
	$files = scandir("/etc/phpshellsessions/");
196
	foreach ($files as $file) {
197
		if ($file <> "." && $file <> "..") {
198
			$playback_files[] = $file;
199
		}
200
	}
201
	return $playback_files;
202
}
203

    
204
if ($argc < 2) {
205
	echo "Welcome to the {$g['product_name']} developer shell\n";
206
	echo "\nType \"help\" to show common usage scenarios.\n";
207
	echo "\nAvailable playback commands:\n     ";
208
	$tccommands[] = "playback";
209
	$playback_files = get_playback_files();
210
	foreach ($playback_files as $pbf) {
211
		echo "{$pbf} ";
212
		if (function_exists("readline_add_history")) {
213
			readline_add_history("playback $pbf");
214
			$tccommands[] = "$pbf";
215
		}
216
	}
217
	echo "\n\n";
218
}
219

    
220
$recording = false;
221
$playback_file_split = array();
222
$playbackbuffer = "";
223

    
224
if ($argv[1]=="playback" or $argv[1]=="run") {
225
	if (empty($argv[2]) || !file_exists("/etc/phpshellsessions/" . basename($argv[2]))) {
226
		echo "Error: Invalid playback file specified.\n\n";
227
		show_recordings();
228
		exit(-1);
229
	}
230
	playback_file(basename($argv[2]));
231
	exit;
232
}
233

    
234
// Define more commands
235
$tccommands[] = "exit";
236
$tccommands[] = "quit";
237
$tccommands[] = "?";
238
$tccommands[] = "exec";
239
$tccommands[] = "stoprecording";
240
$tccommands[] = "showrecordings";
241
$tccommands[] = "record";
242
$tccommands[] = "reset";
243
$tccommands[] = "master";
244
$tccommands[] = "RELENG_1_2";
245

    
246
while ($shell_active == true) {
247
	$command = readline("{$g['product_name']} shell: ");
248
	readline_add_history($command);
249
	$command_split = explode(" ", $command);
250
	$first_command = $command_split[0];
251
	if ($first_command == "playback" || $first_command == "run") {
252
		$playback_file = $command_split[1];
253
		if (!$playback_file || !file_exists("/etc/phpshellsessions/{$playback_file}")) {
254
			$command = "";
255
			echo "Could not locate playback file.\n";
256
		} else {
257
			$command = "";
258
			echo "\nPlayback of file {$command_split[1]} started.\n\n";
259
			playback_file("{$playback_file}");
260
			continue;
261
		}
262
	}
263
	if ($first_command == "exit" or $first_command == "quit") {
264
		die;
265
	}
266
	if ($first_command == "help" or $first_command == "?") {
267
		show_help();
268
		$playbackbuffer = "";
269
		continue;
270
	}
271
	if ($first_command == "exec" or $first_command == "exec;") {
272
		playback_text($playbackbuffer);
273
		$playbackbuffer = "";
274
		continue;
275
	}
276
	if ($first_command == "stoprecording" || $first_command == "stoprecord" || $first_command == "stop") {
277
		if ($recording) {
278
			fwrite($recording_fd, $playbackbuffer);
279
			fclose($recording_fd);
280
			$command = "";
281
			echo "Recording stopped.\n";
282
			$recording = false;
283
		} else {
284
			echo "No recording session in progress.\n";
285
			$command = "";
286
		}
287
	}
288
	if ($first_command == "showrecordings") {
289
		show_recordings();
290
		$command = "";
291
	}
292
	if ($first_command == "reset") {
293
		$playbackbuffer = "";
294
		echo "\nBuffer reset.\n\n";
295
		continue;
296
	}
297
	if ($first_command == "record") {
298
		if (!$command_split[1]) {
299
			echo "usage: record playbackname\n";
300
			echo "\tplaybackname will be created in /etc/phpshellsessions.\n";
301
			$command = "";
302
		} else {
303
			/* time to record */
304
			safe_mkdir("/etc/phpshellsessions");
305
			$recording_fn = basename($command_split[1]);
306
			$recording_fd = fopen("/etc/phpshellsessions/{$recording_fn}","w");
307
			if (!$recording_fd) {
308
				echo "Could not start recording session.\n";
309
				$command = "";
310
			} else {
311
				$recording = true;
312
				echo "Recording of {$recording_fn} started.\n";
313
				$command = "";
314
			}
315
		}
316
	}
317
	$playbackbuffer .= $command . "\n";
318
}
319

    
320
function show_recordings() {
321
	echo "==> Sessions available for playback are:\n";
322
	$playback_files = get_playback_files();
323
	foreach (get_playback_files() as $pbf) {
324
		echo "{$pbf} ";
325
	}
326
	echo "\n\n";
327
	echo "==> end of list.\n";
328
}
329

    
330
function returnlastchar($command) {
331
	$commandlen = strlen($command);
332
	$endofstring = substr($command, ($commandlen-1));
333
	return $endofstring;
334
}
335

    
336
function returnfirstchar($command) {
337
	$commandlen = strlen($command);
338
	$endofstring = substr($command, 0, 1);
339
	return $endofstring;
340
}
341

    
342
function str_replace_all($search,$replace,$subject) {
343
	while (strpos($subject,$search)!==false) {
344
		$subject = str_replace($search,$replace,$subject);
345
	}
346
	return $subject;
347
}
348

    
349
function playback_text($playback_file_contents) {
350
	$playback_file_split = explode("\n", $playback_file_contents);
351
	$playback_text  = "require_once('functions.inc');\n";
352
	$playback_text .= "require_once('globals.inc');\n";
353
	$playback_text .= "require_once('config.inc');\n";
354
	$toquote = '"';
355
	$toquotereplace = '\\"';
356
	foreach ($playback_file_split as $pfs) {
357
		$firstchar = returnfirstchar($pfs);
358
		$currentline = $pfs;
359
		if ($firstchar == "!") {
360
			/* XXX: encode " in $pfs */
361
			$pfsa = str_replace($toquote, $toquotereplace, $currentline);
362
			$playback_text .= str_replace("!", "system(\"", $pfsa) . "\");\n";
363
		} else if ($firstchar == "=") {
364
			/* XXX: encode " in $pfs */
365
			$pfsa = str_replace($toquote, $toquotereplace, $currentline);
366
			$currentline   .= str_replace("!", "system(\"", $pfsa) . "\");\n";
367
		} else {
368
			$playback_text .= $pfs . "\n";
369
		}
370
	}
371
	global $config;
372
	eval($playback_text);
373
}
374

    
375
function playback_file($playback_file) {
376
	$playback_file_contents = file_get_contents("/etc/phpshellsessions/{$playback_file}");
377
	playback_text($playback_file_contents);
378
}
379

    
380
?>
(11-11/23)