Mini Shell

Direktori : /opt/sharedrads/
Upload File :
Current File : //opt/sharedrads/vhost_data.py

#! /opt/imh-python/bin/python3
''' Gather important VirtualHost information. '''

import re
import os
import json
import logging
from argparse import ArgumentParser

import envinfo

LOGGER = logging.getLogger(__name__)

__author__ = "Daniel K"
__email__ = "danielk@inmotionhosting.com"


def get_vhost_list(conf=None):
    '''Collect necessary information from VirtualHost entries.'''

    if conf is None:
        conf = envinfo.get_data()['apache_conf']

    vhost_list = []

    vhost_rx = re.compile(
        r'<VirtualHost (?P<ip>[0-9.]+):(?P<port>[0-9]+)( ([0-9.]+):([0-9]+))*>'
    )

    if os.path.exists(conf):
        with open(conf, encoding='utf-8') as file_handle:
            vhost_data = {}
            vhost_data['hostnames'] = []
            try:
                for line in file_handle:
                    vhost_match = vhost_rx.search(line)

                    if "#" not in line:
                        if "/VirtualHost" in line:
                            if 'ip' in vhost_data:
                                if 'port' in vhost_data:
                                    vhost_list.append(vhost_data)
                            vhost_data = {}
                            vhost_data['hostnames'] = []
                        elif vhost_match is not None:
                            vhost_data['ip'] = vhost_match.group('ip')
                            vhost_data['port'] = vhost_match.group('port')
                        elif "ServerName" in line:
                            vhost_data['hostnames'].append(line.split()[1])
                        elif "ServerAlias" in line:
                            line = line.strip()
                            for host in line.split(" ", 1)[1].split():
                                vhost_data['hostnames'].append(host)
                        elif "Include" in line:
                            if 'includes' not in vhost_data:
                                vhost_data['includes'] = []
                            vhost_data['includes'].append(line.split()[1])
                        elif "SSLCertificateFile" in line:
                            vhost_data['ssl'] = line.split()[1]
                        elif "SSLCertificateKeyFile" in line:
                            vhost_data['key'] = line.split()[1]
                        elif "SSLCertificateChainFile" in line:
                            vhost_data['ca'] = line.split()[1]
                        elif "DocumentRoot" in line:
                            vhost_data['docroot'] = line.split()[1]
            except OSError:
                LOGGER.error("Error reading file")
                return None

    return vhost_list


def search_vhost_list(vhost_list, host=None, ip_address=None, port=None):
    '''Search vhost_list for first matching entry for given information'''

    if vhost_list is None:
        vhost_list = get_vhost_list()

    working_list = []

    for vhost_data in vhost_list:
        if (ip_address is None) or (ip_address in vhost_data['ip']):
            if (port is None) or (port in vhost_data['port']):
                working_list.append(vhost_data)

    if len(working_list) == 0:
        for vhost_data in vhost_list:
            if (ip_address is None) or (ip_address in vhost_data['ip']):
                if '*' in vhost_data['port']:
                    working_list.append(vhost_data)

    if len(working_list) == 0:
        return vhost_list[1]

    for vhost_data in working_list:
        if host in vhost_data['hostnames']:
            return vhost_data

    return None


def parse_args():
    '''Parse command line aruments'''

    parser = ArgumentParser(description=__doc__)

    output_parser_group = parser.add_argument_group("Output options")
    output_group = output_parser_group.add_mutually_exclusive_group()

    output_group.add_argument(
        "-d",
        "--documentroot",
        action='store_true',
        help="Output only the document root.",
    )

    output_group.add_argument(
        "-j",
        "--json",
        action='store_true',
        help="Output only the document root.",
    )

    parser.add_argument(
        '-c',
        '--config',
        type=str,
        default=None,
        help="Location of a custom Apache configuration.",
    )

    search_group = parser.add_argument_group("Search options")

    search_group.add_argument(
        "-i", "--ip", type=str, default=None, help="IP to search."
    )

    port_group = search_group.add_mutually_exclusive_group()

    port_group.add_argument(
        "-p", "--port", type=str, default=None, help="Port to search."
    )

    port_group.add_argument(
        "-s",
        "--standardports",
        type=str,
        default=None,
        help="Try port 443 first, and if no entry, try port 80.",
    )

    search_group.add_argument("hostname", type=str, help="Hostname to search.")

    args = parser.parse_args()

    if args.documentroot:
        output = "docroot"
    elif args.json:
        output = "json"
    else:
        output = "standard"

    return output, args.ip, args.port, args.hostname, args.config


def main():
    '''Main function for script'''

    (output, ip_address, port, host, conf) = parse_args()

    vhost_list = get_vhost_list(conf)
    vhost_data = search_vhost_list(vhost_list, host, ip_address, port)

    if vhost_data is None:
        print("No results found")
    elif output == "docroot":
        print(vhost_data['docroot'])
    elif output == "json":
        print(
            json.dumps(
                vhost_data, sort_keys=True, indent=4, separators=(',', ': ')
            )
        )
    else:
        print("Hostname: %s" % host)
        print("IP/port: {}:{}".format(vhost_data['ip'], vhost_data['port']))
        print("Document Root: %s" % vhost_data['docroot'])
        if 'ssl' in vhost_data:
            print("SSL Certificate: %s" % vhost_data['ssl'])
            print("SSL Private Key: %s" % vhost_data['key'])
            if 'ca' in vhost_data:
                print("SSL CA Bundle: %s" % vhost_data['ca'])
        if 'includes' in vhost_data:
            for path in vhost_data['includes']:
                print("Include: %s" % path)


if __name__ == "__main__":
    main()

Zerion Mini Shell 1.0