Project

General

Profile

Download (10.3 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-2013 BSD Perimeter
8
 * Copyright (c) 2013-2016 Electric Sheep Fencing
9
 * Copyright (c) 2014-2025 Rubicon Communications, LLC (Netgate)
10
 * All rights reserved.
11
 *
12
 * Licensed under the Apache License, Version 2.0 (the "License");
13
 * you may not use this file except in compliance with the License.
14
 * You may obtain a copy of the License at
15
 *
16
 * http://www.apache.org/licenses/LICENSE-2.0
17
 *
18
 * Unless required by applicable law or agreed to in writing, software
19
 * distributed under the License is distributed on an "AS IS" BASIS,
20
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21
 * See the License for the specific language governing permissions and
22
 * limitations under the License.
23
 */
24

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

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

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

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

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

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

    
102
function show_help() {
103
	global $g;
104

    
105
$show_help_text = <<<EOF
106

    
107
	Enter a series of commands and then execute the set with "exec".
108

    
109
	For example:
110
	echo "foo"; // php command
111
	echo "foo2"; // php command
112
	! echo "heh" # shell command
113
	exec
114

    
115
	Example commands:
116

    
117
	record <recordingfilename>
118
	stoprecording
119
	showrecordings
120

    
121
	config_read_file();  # reloads the config array
122

    
123
	\$temp = print_r(config_get_path(''), true);
124
	more(\$temp);
125

    
126
	/* to output a configuration array */
127
	print_r(config_get_path(''));
128

    
129
	/* to output the interfaces configuration portion of config.xml */
130
	print_r(config_get_path('interfaces'));
131

    
132
	/* to output the dhcp server configuration */
133
	print_r(config_get_path('dhcpd'));
134

    
135
	/* to exit the {$g['product_label']} developer shell */
136
	exit
137

    
138
	/* to output supported wireless modes for an interface */
139
	print_r(get_wireless_modes(\"ath0\"));
140

    
141
	/* to enable SSH */
142
	config_set_path('system/ssh/enable', "enabled");
143

    
144
	/* change OPTX to the OPT interface name such as BACKHAUL */
145
	config_set_path('interfaces/optx/wireless/standard', "11a");
146
	config_set_path('interfaces/optx/wireless/mode', "hostap");
147
	config_set_path('interfaces/optx/wireless/channel', "6");
148

    
149
	/* to enable dhcp server for an optx interface */
150
	config_set_path('dhcpd/optx/enable', true);
151
	config_set_path('dhcpd/optx/range/from', "192.168.31.100");
152
	config_set_path('dhcpd/optx/range/to', "192.168.31.150");
153

    
154
	/* to disable the firewall filter */
155
	config_set_path('system/disablefilter', true);
156

    
157
	/* to enable an interface and configure it as a DHCP client */
158
	config_set_path('interfaces/optx/disabled', false);
159
	config_set_path('interfaces/optx/ipaddr', "dhcp");
160

    
161
	/* to enable an interface and set a static IPv4 address */
162
	config_set_path('interfaces/wan/enable', true);
163
	config_set_path('interfaces/wan/ipaddr', "192.168.100.1");
164
	config_set_path('interfaces/wan/subnet', "24");
165

    
166
	/* to save out the new configuration (config.xml) */
167
	write_config();
168

    
169
	/* to reboot the system after saving */
170
	system_reboot_sync();
171

    
172
EOF;
173

    
174
	more($show_help_text);
175

    
176
}
177

    
178
$fp = fopen('php://stdin', 'r');
179

    
180
if ($argc < 2) {
181
	echo ".\n\n";
182
}
183

    
184
$pkg_interface='console';
185

    
186
$shell_active = true;
187
$tccommands = array();
188

    
189
function completion($string, $index) {
190
	global $tccommands;
191
	return $tccommands;
192
}
193

    
194
readline_completion_function("completion");
195

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

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

    
223
$recording = false;
224
$playback_file_split = array();
225
$playbackbuffer = "";
226

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

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

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

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

    
333
function returnlastchar($command) {
334
	$commandlen = strlen($command);
335
	$endofstring = substr($command, ($commandlen-1));
336
	return $endofstring;
337
}
338

    
339
function returnfirstchar($command) {
340
	$commandlen = strlen($command);
341
	$endofstring = substr($command, 0, 1);
342
	return $endofstring;
343
}
344

    
345
function str_replace_all($search,$replace,$subject) {
346
	while (strpos($subject,$search)!==false) {
347
		$subject = str_replace($search,$replace,$subject);
348
	}
349
	return $subject;
350
}
351

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

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

    
382
?>
(19-19/38)