Skip to content

w3af's dependency check

andresriancho edited this page Sep 5, 2014 · 1 revision

Introduction

Since packaging w3af for every operating system and/or distribution was impossible given my time restrictions, I decided to work on a module that checks if all the required dependencies are installed and if not give the user the commands required to install them in his specific platform.

Entry point

The dependency check function is called at the beginning of the w3af_gui and w3af_console scripts and verifies if all the dependencies are properly installed. The code looks like this:

# Check if I have all needed dependencies
from w3af.core.controllers.dependency_check.dependency_check import dependency_check
dependency_check()

When there are missing dependencies, it will output a message explaining what's missing, how to fix the error and finally it will exit.

Supported platforms

The list of supported platforms can be found here. An example platform file looks like this:

import subprocess
import platform

from .base_platform import Platform
from ..requirements import CORE, GUI


class Ubuntu1204(Platform):
    SYSTEM_NAME = 'Ubuntu 12.04'
    PKG_MANAGER_CMD = 'sudo apt-get install'
    PIP_CMD = 'pip'

    CORE_SYSTEM_PACKAGES = ['python-pip', 'python2.7-dev',
                            'python-setuptools', 'build-essential',
                            'libsqlite3-dev', 'libssl-dev', 'git',
                            'libxml2-dev', 'libxslt1-dev', 'libyaml-dev']

    GUI_SYSTEM_PACKAGES = CORE_SYSTEM_PACKAGES[:]
    GUI_SYSTEM_PACKAGES.extend(['graphviz', 'python-gtksourceview2',
                                'python-gtk2'])

    SYSTEM_PACKAGES = {CORE: CORE_SYSTEM_PACKAGES,
                       GUI: GUI_SYSTEM_PACKAGES}

    @staticmethod
    def os_package_is_installed(package_name):
        not_installed = 'is not installed and no info is available'

        # The hold string was added after a failed build of w3af-module
        installed = 'Status: install ok installed'
        hold = 'Status: hold ok installed'

        try:
            p = subprocess.Popen(['dpkg', '-s', package_name],
                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except OSError:
            # We're not on a debian based system
            return None
        else:
            dpkg_output, _ = p.communicate()

            if not_installed in dpkg_output:
                return False
            elif installed in dpkg_output or hold in dpkg_output:
                return True
            else:
                return None

    @staticmethod
    def is_current_platform():
        return 'Ubuntu' in platform.dist() and '12.04' in platform.dist()

Let's analyze the constants defined above:

  • SYSTEM_NAME: A string specifying the name of the platform
  • PKG_MANAGER_CMD: The command to be used in this platform to install the missing operating system packages
  • PIP_CMD: The path to the pip package manager
  • CORE_SYSTEM_PACKAGES: List of operating system packages which are required by w3af to run. These are checked by the os_package_is_installed method and if missing we'll show a message to the user containing PKG_MANAGER_CMD and the packages.
  • GUI_SYSTEM_PACKAGES: List of operating system packages which are required to run w3af's GUI.
  • SYSTEM_PACKAGES: A simple dict with a map of the dependencies

A very important part of this code is the is_current_platform method, which will try to match the current platform where w3af is run in the most specific way possible. This allows us to show the user custom help for his operating system and distribution version. When creating a new platform make sure you're specific about versions and distributions.

When creating a new platform it might be also a good idea for you to take a look at the parent class Platform.

Hooking a new platform class into the dependency check

Just add your class to this list and you're all set.