# XML Output #
# Does anyone use XML output?
# We'd love to hear any suggestions you may have!
# Does it bother you that some types of output are joined by commas
# but other types aren't?
class LoggingXML < Logging
def initialize(f = STDOUT)
super
@substitutions = { '&' => '&', '"' => '"', '<' => '<', '>' => '>' }
# only output '
end
@f.puts ''
end
def close
@f.puts ''
@f.close
end
def escape(t)
text = t.to_s.dup
# use sort_by so that & is before ", etc.
@substitutions.sort_by { |a, _| a == '&' ? 0 : 1 }.map { |from, to| text.gsub!(from, to) }
# Encode all special characters
# More info: http://www.asciitable.com/
r = /[^\x20-\x5A\x5E-\x7E]/
# based on code for CGI.escape
text.gsub!(r) { |x| "%#{x.unpack('H2' * x.size).join('%').upcase}" }
text
end
def out(target, status, results)
$semaphore.synchronize do
@f.puts ''
@f.puts "\t#{escape(target)}"
@f.puts "\t#{escape(status)}"
@f.puts "\t"
@f.puts "\t\t" if $USE_PROXY
@f.puts "\t\t\t#{escape($PROXY_HOST)}:#{escape($PROXY_PORT)}" if $PROXY_HOST && $PROXY_PORT
@f.puts "\t\t\t#{escape($PROXY_USER)}" if $PROXY_USER
@f.puts "\t\t" if $USE_PROXY
$CUSTOM_HEADERS.each do |header_name, header_value|
@f.puts "\t\t"
@f.puts "\t\t\t#{escape(header_name)}"
@f.puts "\t\t\t#{escape(header_value)}"
@f.puts "\t\t"
end
@f.puts "\t"
results.each do |plugin_name, plugin_results|
@f.puts "\t"
@f.puts "\t\t#{escape(plugin_name)}"
unless plugin_results.empty?
# important info in brief mode is version, type and ?
# what's the highest probability for the match?
certainty = plugin_results.map do |x|
x[:certainty] unless x[:certainty].class == Regexp
end.flatten.compact.sort.uniq.last
version = plugin_results.map do |x|
x[:version] unless x[:version].class == Regexp
end.flatten.compact.sort.uniq
os = plugin_results.map do |x|
x[:os] unless x[:os].class == Regexp
end.flatten.compact.sort.uniq
string = plugin_results.map do |x|
x[:string] unless x[:string].class == Regexp
end.flatten.compact.sort.uniq
model = plugin_results.map do |x|
x[:model] unless x[:model].class == Regexp
end.flatten.compact.sort.uniq
firmware = plugin_results.map do |x|
x[:firmware] unless x[:firmware].class == Regexp
end.flatten.compact.sort.uniq
filepath = plugin_results.map do |x|
x[:filepath] unless x[:filepath].class == Regexp
end.flatten.compact.sort.uniq
account = plugin_results.map do |x|
x[:account] unless x[:account].class == Regexp
end.flatten.compact.sort.uniq
modules = plugin_results.map do |x|
x[:module] unless x[:module].class == Regexp
end.flatten.compact.sort.uniq
# Output results
@f.puts "\t\t#{escape(certainty)}" if certainty && certainty < 100
version.map { |x| @f.puts "\t\t#{escape(x)}" }
os.map { |x| @f.puts "\t\t#{escape(x)}" }
string.map { |x| @f.puts "\t\t#{escape(x)}" }
model.map { |x| @f.puts "\t\t#{escape(x)}" }
firmware.map { |x| @f.puts "\t\t#{escape(x)}" }
filepath.map { |x| @f.puts "\t\t#{escape(x)}" }
account.map { |x| @f.puts "\t\t#{escape(x)}" }
modules.map { |x| @f.puts "\t\t#{escape(x)}" }
end
@f.puts "\t"
end
@f.puts ''
end
end
end