Esempio n. 1
0
def main():
    global log

    args = parse_args()
    log = get_logger('issues-cron' if args.cron else 'issues')

    args.func(args)
Esempio n. 2
0
def main():
    global log, pipes

    log = get_logger('server')

    ports = None
    port = get_server_setting('port')
    if isinstance(port, int):
        ports = [port]
    elif isinstance(port, dict):
        ports = list(port.keys())
    local_port = get_server_setting('local_port')
    if local_port in ports:
        sys.exit('Configuration error! Local port {} is also configured as a '
                 'non-local port.'.format(local_port))
    ports.append(local_port)

    prepare_database()

    children = {}

    def sigint_handler(*args):
        for p in children.values():
            try:
                os.kill(p.pid, signal.SIGINT)
            except:
                pass

    with Manager() as manager:
        pipes = manager.dict()
        clean_up_pipes()
        for port in ports:
            p = Process(target=startServer,
                        args=(port, pipes),
                        kwargs={'local_only': port == local_port})
            p.daemon = True
            p.start()
            children[port] = p

        # Make sure the children didn't die on startup, e.g., because they
        # couldn't bind to their ports.
        time.sleep(1)
        problems = False
        for port in children.keys():
            if not children[port].is_alive():
                log.error(
                    'Child process for port {} died on startup. Maybe '
                    'its port is in use?', port)
                problems = True
        if problems:
            sigint_handler()
            log.error('Exiting because one or more servers failed to start up')
            sys.exit(1)

        signal.signal(signal.SIGINT, sigint_handler)
        for p in children.values():
            p.join()
Esempio n. 3
0
def startServer(port, pipes_arg, local_only=False):
    global log, pipes, encryptors

    # To enable keep-alive
    WSGIRequestHandler.protocol_version = 'HTTP/1.1'
    # To prevent DoS attacks by opening connections and not closing them and
    # consuming resources and filling all our connection slots in the kernel.
    WSGIRequestHandler.timeout = 10

    log = get_logger('server')
    pipes = pipes_arg
    encryptors = defaultdict(dict)
    clean_up_encryptors()

    werkzeug._internal._logger = logging.getLogger(log.name)

    if not local_only:
        app.config['deprecated_port'] = get_port_setting(
            port, 'deprecated', False)

    # Logbook will handle all logging, via the root handler installed by
    # `get_logger` when it alls `logbook.compat.redirect_logging()`.
    del app.logger.handlers[:]
    app.logger.propagate = True

    # Werkzeug has a bug which causes sockets to get stuck in TCP CLOSE_WAIT
    # state. Eventually, there are so many stuck sockets that the kernel stops
    # allowing new connections to the port, and then attempts to connect to the
    # port by clients hang. The "real" way to fix this is to run the server
    # under a different WSGI framework, but all of them are more of a pain to
    # set up than werkzeug, so I'm hoping that we can solve this problem just
    # by handling each request in a separate process so the socket for each
    # request will get closed properly when its process exits.
    # More info: https://stackoverflow.com/questions/31403261/\
    # flask-werkzeug-sockets-stuck-in-close-wait
    kwargs = {'processes': 10}
    if local_only:
        host = '127.0.0.1'
    else:
        host = '0.0.0.0'

        ssl_certificate = get_port_setting(port, 'ssl:certificate', None)
        ssl_key = get_port_setting(port, 'ssl:key', None)
        ssl_enabled = get_port_setting(port, 'ssl:enabled',
                                       bool(ssl_certificate))
        if bool(ssl_certificate) + bool(ssl_key) == 1:
            raise Exception(
                'You must specify both certificate and key for SSL!')

        if ssl_enabled:
            kwargs['ssl_context'] = (ssl_certificate, ssl_key)

    run_simple(host, port, app, **kwargs)
    get_db,
    get_setting as get_server_setting,
    set_setting as set_server_setting,
    save_settings as save_server_settings,
    get_selectors,
    encrypt_document,
    get_logger,
)
from penguindome.client import (
    set_setting as set_client_setting,
    save_settings as save_client_settings,
)

os.chdir(top_dir)
set_gpg('server')
log = get_logger('secret_keeping')

selectors_setting = 'secret_keeping:selectors'
restart_note = ("\nNOTE: Don't forget to build a new client release!\n")
distribute_secrets_note = '''
The {m} pieces of the secret-keeping key are in this directory:

{split_dir}

Please distribute these files securely to the secret-keepers and then remove
them with "shred -u". At least {n} of these files will need to be provided to
reconstruct the key so that secret data can be decrypted.
'''
audit_trail_selectors = (SelectorVariants('old', 'old', 'old', 'old'),
                         SelectorVariants('new', 'new', 'new', 'new'))
Esempio n. 5
0
#!/usr/bin/env python

import argparse
import curses

from penguindome import set_gpg
from penguindome.server import patch_hosts, get_setting, get_logger
from penguindome.shell import (
    InteractionBroker,
    TerminalPeer,
    PenguinDomeServerPeer,
)

set_gpg('server')
log = get_logger('client_shell')


def interact(stdscr, broker):
    curses.raw()
    broker.interact()


def parse_args():
    parser = argparse.ArgumentParser(
        description='Request a remote shell on a client',
        epilog='Remote shell traffic travels through and is mediated by the '
        'server. This script tells the server to send a remote shell request '
        'to the specified client, Then connects to the server and waits for '
        'the client to initiate the remote shell. Once the remote shell is '
        'initiated, you can interact with it normally. To exit from the '
        'shell, hit Enter followed by "~." (tilde, then period).')
Esempio n. 6
0
#!/usr/bin/env python

import argparse
import logbook
import sys

from penguindome.server import (
    valid_client_parameters,
    set_client_parameter,
    get_client_parameter,
    get_client_parameters,
    get_logger,
)

log = get_logger('client_parameters')


def parse_args(args=None):
    parser = argparse.ArgumentParser(
        description='Administer client parameters')
    if sys.version_info >= (3, 7):  # Only works from Python 3.7.0
        subparsers = parser.add_subparsers(dest='command', required=True)
    else:
        subparsers = parser.add_subparsers()

    ls_parser = subparsers.add_parser('ls',
                                      help='List client parameters',
                                      aliases=('list', ))
    ls_parser.set_defaults(func=ls_handler)
    ls_parser.add_argument('--hostname',
                           action='append',
Esempio n. 7
0
import shutil
import subprocess
import sys

from penguindome import (
    top_dir,
    set_gpg,
    release_files_iter,
    signatures_dir,
    verify_signature,
)
from penguindome.server import get_logger, sign_file

os.chdir(top_dir)

log = get_logger('sign')


def parse_args():
    parser = argparse.ArgumentParser(description='Generate digital signatures '
                                     'for client files')
    parser.add_argument('--full',
                        action='store_true',
                        help='Regenerate all '
                        'signatures rather than only invalid ones')

    args = parser.parse_args()
    return args


def main():
"""

import argparse
import datetime
import dateutil.parser
import gzip
from io import BytesIO
from pymongo import ASCENDING
from pymongo.errors import DuplicateKeyError
import re
import requests
import xml.etree.ElementTree as ET

from penguindome.server import get_db, get_logger, arch_security_flag

log = get_logger('plugin_managers/arch_os_updates')


def rss_feed():
    url = 'https://security.archlinux.org/advisory/feed.atom'
    response = requests.get(url)
    response.raise_for_status()
    root = ET.fromstring(response.content)
    ns_string = re.match(r'({.*})', root.tag).group(1)

    def ns(tag):
        return '{}{}'.format(ns_string, tag)

    package_re = re.compile(r'^.*\] ([^:]+):')

    matched_one = False