<?php
	// Run an command over ssh providing a password on the command line
	// Version 1.0 Trevor White 18 Jul 2013
	// Version 1.1 Trevor White 25 Jul 2013 - Added terminal emulation for shells that won't close


	// Return Codes
	define ("NAGIOS_OK", 0);
	define ("NAGIOS_WARNING", 1);
	define ("NAGIOS_ERROR", 2);
	define ("NAGIOS_UNKNOWN", 3);

	function DisplayUsage ($message) {
		// Usage Information
		echo "****SSH Online Password Authentication System v1.1***" . PHP_EOL .
		"Connects over ssh using a username and password" . PHP_EOL .
		__FILE__ . " -h [HOSTIP] -u [USER] -p [PASS] -t -d -m -c [COMMAND]" . PHP_EOL .
		"-m   Mulitple commands, parse each seperately, seperate with ; in the command string" . PHP_EOL .
		"-d   Debug, print what's happening" . PHP_EOL .
		"-t   Open a virtual terminal (used if you are having problems with the standard mode)" . PHP_EOL
		. PHP_EOL .
		"$message" . PHP_EOL;
		exit (NAGIOS_UNKNOWN);
	}


	$options = getopt ("tdmh:u:p:c:");

	if (! is_array ($options)) {
		DisplayUsage ("There was a problem getting the required options");
	}

	if ((empty($options["u"])) || (empty($options["p"])) || (empty($options["c"])) || (empty($options["h"]))) {
		DisplayUsage ("Required options not set");
	}

	if ( isset($options['d'])) { echo "Starting Connection" . PHP_EOL; }
	$ssh = ssh2_connect($options["h"], 22);

	if (! $ssh ) {
		// Failed
		echo "Failed to Connect to ${options['h']}" . PHP_EOL;
		exit (NAGIOS_UNKNOWN);
	}

	// Should be connected
	if ( isset($options['d'])) { echo "Sending Password" . PHP_EOL; }
	if ( ! ssh2_auth_password ( $ssh, $options['u'], $options['p'] ) ) {
		// Failed to Connect
		echo "Authentication Failed" . PHP_EOL;
		unset ($ssh);
		exit (NAGIOS_UNKNOWN);
	}

	// Connected and authenticated
	if ( isset($options['m'])) {
		if ( isset($options['d'])) { echo "Preparing Multiple Commands..." . PHP_EOL; }
		$commands = explode (";", $options['c']);
	} else {
		if ( isset($options['d'])) { echo "Preparing Single Command..." . PHP_EOL; }
		$commands[0] = $options['c'];
	}
	if (isset($options['t'])) {
		if ( isset($options['d'])) { echo "Opening Terminal Window" . PHP_EOL; }
		$stream = ssh2_shell ($ssh, 'xterm', null, 200, 200, SSH2_TERM_UNIT_CHARS);
		if ( isset($options['d'])) { echo "Blocking Stream" . PHP_EOL; }
		$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
		stream_set_blocking ($stream, true);
		stream_set_blocking($errorStream, true);
	}
		

	foreach ( $commands as $command ) {
		if (isset($options['t'])) {
			// Terminal
			if ( isset($options['d'])) { echo "Sending Command (To Terminal) {{$command}}" . PHP_EOL; }
			fwrite ($stream, $command . PHP_EOL );
			sleep(2);
		} else {
			// Exec
			if ( isset($options['d'])) { echo "Sending Command (Online) {{$command}}" . PHP_EOL; }
			$stream = ssh2_exec ($ssh, $command);

			$errorStream = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
			// Wait for completion
			if ( isset($options['d'])) { echo "Blocking Stream" . PHP_EOL; }
			stream_set_blocking ($stream, true);
			stream_set_blocking($errorStream, true);
		}
		
		// Echo data
		if ( ! isset ($options['t']) ){
			// Only process not if not in a terminal
			if ( isset($options['d'])) { echo "Getting Main Stream" . PHP_EOL; }
			echo stream_get_contents($stream);
			if ( isset($options['d'])) { echo "Getting Error Stream" . PHP_EOL; }
			$errbuf=stream_get_contents($errorStream);

			// Check Error Stream
			if ( isset($options['d'])) { echo "Getting Error Stream" . PHP_EOL; }
			if (strlen($errbuf) > 0 ) {
				// Append Data
				$errortext .= PHP_EOL . $errbuf;
			} else {
				// New Data
				$errortext = $errbuf;
			}
		}
	}

	if (isset($options['t'])) {
		// Process streams now
		if ( isset($options['d'])) { echo "Requesting Stream Close" . PHP_EOL; }
		fwrite ($stream, "exit" . PHP_EOL );
		sleep (2);
		echo stream_get_contents($stream);
		$errortext=stream_get_contents($errorStream);
	}

	// Close Connection, give time for the feeds to stop
	sleep (5);
	fClose($stream);
	fClose($errorStream);
	unset ($ssh);


	if (strlen($errortext) > 0) {
		// Error Data
		echo "Error Data: $errortext";
		exit (NAGIOS_ERROR);
	}
	
	// All Good
	exit (NAGIOS_OK);	
		


?>
