class Pedant::CheckContainsRegistrationSection

Public Class Methods

requires() click to toggle source
Calls superclass method Pedant::Check::requires
# File lib/pedant/checks/contains_registration_section.rb, line 29
def self.requires
  super + [:main, :trees]
end

Public Instance Methods

run() click to toggle source
# File lib/pedant/checks/contains_registration_section.rb, line 33
def run
  # This check only applies to plugins.
  return skip unless @kb[:main].extname == '.nasl'

  # This check will pass by default.
  pass

  tree = @kb[:trees][@kb[:main]]

  # Find the registration If statement.
  regs = tree.all(:If).select do |node|
    (node.cond.is_a?(Nasl::Lvalue) && node.cond.ident.name == 'description' && node.cond.indexes == [])
  end

  # Ensure there's a registration section.
  if regs.empty?
    report(:error, "No registration section was found.")
    report(:error, "This will cause the plugin to be run twice in both Nessus interface and nasl with the -M flag.")
    return fail
  end

  # Ensure that there is only one registration section.
  unless regs.length == 1
    report(:error, "Multiple registration sections were found.")
    regs.each { |reg| report(:error, reg.context) }
    return fail
  end

  # Ensure that the registration section is a block.
  reg = regs.first
  branch = reg.true
  unless branch.is_a? Nasl::Block
    report(:error, "The registration section is a #{branch.class.name}, but a Block was expected.")
    report(:error, branch.context(reg))
    return fail
  end

  # Ensure that the registration section is not empty.
  if branch.body.empty?
    report(:error, "The registration section is empty.")
    report(:error, branch.context(reg))
    return fail
  end

  # Ensure that the description section ends with a call to exit.
  statement = branch.body.last
  unless statement.is_a? Nasl::Call
    report(:error, "The registration section ends with a #{statement.class.name}, not a Call as expected.")
    report(:error, statement.context(reg))
    return fail
  end

  unless statement.name.indexes == []
    report(:error, "The registration section ends with a call to something other than exit.")
    report(:error, statement.context(reg))
    return fail
  end

  unless statement.name.ident.name == 'exit'
    report(:error, "The registration section ends with a call to #{statement.name.ident.name}, not exit as expected.")
    report(:error, statement.context(reg))
    return fail
  end

  # Ensure that the call to exit is a success without a message.
  args = statement.args
  if args.empty?
    report(:error, "The registration ends with a call to exit with no arguments.")
    report(:error, statement.context)
    return fail
  end

  arg = args.first
  if args.length != 1 || arg.type != :anonymous || !arg.expr.is_a?(Nasl::Integer) || arg.expr.value != 0
    report(:error, "The registration section does not end with a call to exit(0).")
    report(:error, arg.context(statement))
    return fail
  end
end