Esempio n. 1
0
def install_waptserver_service(options, conf=None):
    if conf is None:
        conf = waptserver.config.load_config(options.configfile)
    print("install waptserver")
    service_binary = os.path.abspath(
        os.path.join(wapt_root_dir, 'waptpython.exe'))
    service_parameters = '"%s"' % os.path.join(wapt_root_dir, 'waptserver',
                                               'server.py')
    service_logfile = os.path.join(log_directory, 'nssm_waptserver.log')
    service_dependencies = 'WAPTPostgresql'
    install_windows_nssm_service('WAPTServer', service_binary,
                                 service_parameters, service_logfile,
                                 service_dependencies)

    tasks_db = os.path.join(wapt_root_dir, 'db')
    mkdir_p(tasks_db)
    setuphelpers.run(r'icacls "%s" /grant  "*S-1-5-20":(OI)(CI)(M)' % tasks_db)

    if not conf.get('secret_key'):
        conf['secret_key'] = ''.join(
            random.SystemRandom().choice(string.letters + string.digits)
            for _ in range(64))
        waptserver.config.write_config_file(options.configfile, conf)

    if options.setpassword:
        conf['wapt_password'] = pbkdf2_sha256.hash(
            base64.b64decode(options.setpassword).encode('utf8'))
        waptserver.config.write_config_file(options.configfile, conf)

    # ensure Packages index
    repo = WaptLocalRepo(conf['wapt_folder'])
    repo.update_packages_index()
Esempio n. 2
0
def install_postgresql_service(options, conf=None):
    if conf is None:
        conf = waptserver.config.load_config(options.configfile)
    print("install postgres database")

    pgsql_root_dir = r'%s\waptserver\pgsql-9.6' % wapt_root_dir
    pgsql_data_dir = r'%s\waptserver\pgsql_data-9.6' % wapt_root_dir
    pgsql_data_dir = pgsql_data_dir.replace('\\', '/')

    print("build database directory")
    if not os.path.exists(os.path.join(pgsql_data_dir, 'postgresql.conf')):
        setuphelpers.mkdirs(pgsql_data_dir)

        # need to have specific write acls for current user otherwise initdb fails...
        setuphelpers.run(r'icacls "%s" /t /grant  "%s":(OI)(CI)(M)' %
                         (pgsql_data_dir, GetUserName()))

        setuphelpers.run(r'"%s\bin\initdb" -U postgres -E=UTF8 -D "%s"' %
                         (pgsql_root_dir, pgsql_data_dir))
        setuphelpers.run(r'icacls "%s" /t /grant  "*S-1-5-20":(OI)(CI)(M)' %
                         pgsql_data_dir)

        print("start postgresql database")

        if setuphelpers.service_installed('WaptPostgresql'):
            if setuphelpers.service_is_running('WaptPostgresql'):
                setuphelpers.service_stop('waptPostgresql')
            setuphelpers.service_delete('waptPostgresql')

        cmd = r'"%s\bin\pg_ctl" register -N WAPTPostgresql -U "nt authority\networkservice" -S auto -D "%s"  ' % (
            pgsql_root_dir, pgsql_data_dir)
        print cmd
        run(cmd)
        setuphelpers.run(r'icacls "%s" /grant  "*S-1-5-20":(OI)(CI)(M)' %
                         log_directory)
        setuphelpers.run(r'icacls "%s" /grant  "*S-1-5-20":(OI)(CI)(M)' %
                         pgsql_data_dir)
    else:
        print("database already instanciated, doing nothing")

    # try to migrate from old version (pg 9.4, wapt 1.5)
    old_pgsql_root_dir = r'%s\waptserver\pgsql' % wapt_root_dir
    old_pgsql_data_dir = r'%s\waptserver\pgsql_data' % wapt_root_dir
    old_pgsql_data_dir = old_pgsql_data_dir.replace('\\', '/')

    if os.path.isdir(old_pgsql_data_dir) and os.path.isdir(old_pgsql_root_dir):
        print('migrating database from previous postgresql DB')
        migrate_pg_db(old_pgsql_root_dir, old_pgsql_data_dir, pgsql_root_dir,
                      pgsql_data_dir)

    print('starting postgresql')
    if not setuphelpers.service_is_running('waptpostgresql'):
        setuphelpers.service_start('waptpostgresql')
        # waiting for postgres to be ready
        time.sleep(2)

    print("creating wapt database")
    import psycopg2
    from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
    conn = None
    cur = None
    try:
        conn = psycopg2.connect('dbname=template1 user=postgres')
        conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
        cur = conn.cursor()
        cur.execute("select 1 from pg_roles where rolname='%(db_user)s'" %
                    conf)
        val = cur.fetchone()
        if val is None:
            print(
                "%(db_user)s pgsql user does not exists, creating %(db_user)s user"
                % conf)
            cur.execute("create user %(db_user)s" % conf)

        cur.execute("select 1 from pg_database where datname='%(db_name)s'" %
                    conf)
        val = cur.fetchone()
        if val is None:
            print(
                "database %(db_name)s does not exists, creating %(db_name)s db"
                % conf)
            cur.execute("create database %(db_name)s owner %(db_user)s" % conf)

    finally:
        if cur:
            cur.close()
        if conn:
            conn.close()

    print("Creating/upgrading wapt tables")
    run(r'"%s\waptpython.exe" "%s\waptserver\model.py" init_db -c "%s"' %
        (wapt_root_dir, wapt_root_dir, options.configfile))
    print("Done")

    print('Import lcoal Packages data into database')

    repo = WaptLocalRepo(conf['wapt_folder'])
    load_db_config(conf)
    Packages.update_from_repo(repo)
Esempio n. 3
0
def main():
    global wapt_folder,NGINX_GID

    parser = OptionParser(usage=usage, version=__version__)
    parser.add_option(
        '-c',
        '--config',
        dest='configfile',
        default=waptserver.config.DEFAULT_CONFIG_FILE,
        help='Config file full path (default: %default)')
    parser.add_option(
        "-s",
        "--force-https",
        dest="force_https",
        default=False,
        action='store_true',
        help="Use https only, http is 301 redirected to https (default: False). Requires a proper DNS name")
    parser.add_option(
        '-q',
        '--quiet',
        dest='quiet',
        default=False,
        action="store_true",
        help='Run quiet postconfiguration - default password and simple behavior')

    (options, args) = parser.parse_args()

    quiet = options.quiet

    if not quiet:
        if postconf.yesno("Do you want to launch post configuration tool ?") != postconf.DIALOG_OK:
            print "canceling wapt postconfiguration"
            sys.exit(1)
    else:
        print('WAPT silent post-configuration')

    # SELinux rules for CentOS/RedHat
    if type_redhat():
        if re.match('^SELinux status:.*enabled', run('sestatus')):
            if not quiet:
                postconf.msgbox('SELinux detected, tweaking httpd permissions.')
                selinux_rules()
                postconf.msgbox('SELinux correctly configured for Nginx reverse proxy')
            else:
                print('[*] Redhat/Centos detected, tweaking SELinux rules')
                selinux_rules()
                print('[*] Nginx - SELinux correctly configured for Nginx reverse proxy')

    # Load existing config file
    server_config = waptserver.config.load_config(options.configfile)

    if os.path.isfile(options.configfile):
        print('[*] Making a backup copy of the configuration file')
        datetime_now = datetime.datetime.now()
        shutil.copyfile(options.configfile,'%s.bck_%s'%  (options.configfile,datetime_now.isoformat()) )

    wapt_folder = server_config['wapt_folder']

    # add secret key initialisation string (for session token)
    if not server_config['secret_key']:
        server_config['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64))

    # add user db and password in ini file
    if server_config['db_host'] in (None,'','localhost','127.0.0.1','::1'):
        ensure_postgresql_db(db_name=server_config['db_name'],db_owner=server_config['db_name'],db_password=server_config['db_password'])

    # Password setup/reset screen
    if not quiet:
        if not server_config['wapt_password'] or \
                postconf.yesno("Do you want to reset admin password ?",yes_label='skip',no_label='reset') != postconf.DIALOG_OK:
            wapt_password_ok = False
            while not wapt_password_ok:
                wapt_password = ''
                wapt_password_check = ''

                while wapt_password == '':
                    (code,wapt_password) = postconf.passwordbox("Please enter the wapt server password (min. 10 characters):  ", insecure=True,width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                while wapt_password_check == '':
                    (code,wapt_password_check) = postconf.passwordbox("Please enter the wapt server password again:  ", insecure=True,width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                if wapt_password != wapt_password_check:
                    postconf.msgbox('Password mismatch !')
                elif len(wapt_password) < 10:
                    postconf.msgbox('Password must be at least 10 characters long !')
                else:
                    wapt_password_ok = True

            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password
    else:
        wapt_password = ''
        if not server_config['wapt_password']:
            print('[*] Generating random password for WAPT server')
            wapt_password = pwd.genword(entropy=56, charset="ascii_62")
            print('[*] WAPT admin password : %s' % wapt_password)
            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password

    if not server_config['server_uuid']:
        server_config['server_uuid'] = str(uuid.uuid1())

    # waptagent authentication method
    if not quiet:
        choices = [
                ("1","Allow unauthenticated registration, same behavior as WAPT 1.3", True),
                ("2","Enable kerberos authentication required for machines registration", False),
                ("3","Disable Kerberos but registration require strong authentication", False),
                ]

        code, t = postconf.radiolist("WaptAgent Authentication type?", choices=choices,width=120)
        if code=='cancel':
            print("\n\npostconfiguration canceled\n\n")
            sys.exit(1)
        if t=="1":
            server_config['allow_unauthenticated_registration'] = True
            server_config['use_kerberos'] = False
        if t=="2":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = True
        if t=="3":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = False
    else:
        print('[*] Set default registration method to : Allow anyone to register + Kerberos disabled')
        server_config['allow_unauthenticated_registration'] = True
        server_config['use_kerberos'] = False


    # Guess fqdn using socket
    fqdn = guess_fqdn()

    clients_signing_certificate =  server_config.get('clients_signing_certificate')
    clients_signing_key = server_config.get('clients_signing_key')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn)
        clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn)

        server_config['clients_signing_certificate'] = clients_signing_certificate
        server_config['clients_signing_key'] = clients_signing_key

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn,is_code_signing=False,is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    waptserver.config.write_config_file(cfgfile=options.configfile,server_config=server_config,non_default_values_only=True)

    print('[*] Protecting WAPT config file')
    run("/bin/chmod 640 %s" % options.configfile)
    run("/bin/chown wapt %s" % options.configfile)

    print('[*] Update WAPT repository')
    repo = WaptLocalRepo(wapt_folder)
    repo.update_packages_index(force_all=True)

    final_msg = ['[*] Postconfiguration completed.',]
    if not quiet:
        postconf.msgbox("Press ok to start waptserver and wapttasks daemons")
    enable_waptserver()
    start_waptserver()

    # In this new version Apache is replaced with Nginx? Proceed to disable Apache. After migration one can remove Apache install altogether
    stop_disable_httpd()

    # Nginx configuration
    if quiet:
        try:
            generate_dhparam()
            nginx_cleanup()
            make_httpd_config('/opt/wapt/waptserver', fqdn, options.force_https,server_config)
            enable_nginx()
            restart_nginx()
            setup_firewall()
        except subprocess.CalledProcessError as cpe:
            final_msg += [
                'Error while trying to configure Nginx!',
                'errno = ' + str(cpe.returncode) + ', output: ' + cpe.output
                ]
        except Exception as e:
                import traceback
                final_msg += [
                'Error while trying to configure Nginx!',
                traceback.format_exc()
                ]
    else:
        reply = postconf.yesno("Do you want to configure nginx?")
        if reply == postconf.DIALOG_OK:
            try:
                msg = 'FQDN for the WAPT server (eg. wapt.acme.com)'
                (code, reply) = postconf.inputbox(text=msg, width=len(msg)+4, init=fqdn)
                if code != postconf.DIALOG_OK:
                    exit(1)
                else:
                    fqdn = reply

                generate_dhparam()
                nginx_cleanup()

                if server_config['use_kerberos']:
                    if type_debian():
                        if not check_if_deb_installed('libnginx-mod-http-auth-spnego'):
                            print('[*] Nginx - Missing dependency libnginx-mod-http-auth-spnego, please install first before configuring kerberos')
                            sys.exit(1)

                make_httpd_config('/opt/wapt/waptserver', fqdn, options.force_https, server_config)
                final_msg.append('Please connect to https://' + fqdn + '/ to access the server.')
                postconf.msgbox("The Nginx config is done. We need to restart Nginx?")
                run_verbose('systemctl enable nginx')
                run_verbose('systemctl restart nginx')
                setup_firewall()

            except subprocess.CalledProcessError as cpe:
                final_msg += [
                    'Error while trying to configure Nginx!',
                    'errno = ' + str(cpe.returncode) + ', output: ' + cpe.output
                    ]
            except Exception as e:
                import traceback
                final_msg += [
                'Error while trying to configure Nginx!',
                traceback.format_exc()
                ]

    final_msg.append('Please connect to https://' + fqdn + '/ to access the server.')

    # Check if Mongodb > PostgreSQL migration is necessary
    if not quiet:
        if check_mongo2pgsql_upgrade_needed(options.configfile) and\
                postconf.yesno("It is necessary to migrate current database backend from mongodb to postgres. Press yes to start migration",no_label='cancel') == postconf.DIALOG_OK:
            upgrade2postgres(options.configfile)
    else:
        if check_mongo2pgsql_upgrade_needed(options.configfile):
            upgrade2postgres(options.configfile)

    # Final message
    if not quiet:
        width = 4 + max(10, len(max(final_msg, key=len)))
        height = 2 + max(20, len(final_msg))
        postconf.msgbox('\n'.join(final_msg), height=height, width=width)
    else:
        if wapt_password:
            final_msg.append('[*] WAPT admin password : %s\n' % wapt_password)
        for line in final_msg:
            print(line)
Esempio n. 4
0
def main():
    global wapt_folder, NGINX_GID

    parser = OptionParser(usage=usage, version=__version__)
    parser.add_option('-c',
                      '--config',
                      dest='configfile',
                      default=waptserver.config.DEFAULT_CONFIG_FILE,
                      help='Config file full path (default: %default)')
    parser.add_option(
        "-s",
        "--force-https",
        dest="force_https",
        default=False,
        action='store_true',
        help=
        "Use https only, http is 301 redirected to https (default: False). Requires a proper DNS name"
    )
    parser.add_option(
        '-q',
        '--quiet',
        dest='quiet',
        default=False,
        action="store_true",
        help=
        'Run quiet postconfiguration - default password and simple behavior')

    (options, args) = parser.parse_args()

    quiet = options.quiet

    if not quiet:
        if postconf.yesno("Do you want to launch post configuration tool ?"
                          ) != postconf.DIALOG_OK:
            print("canceling wapt postconfiguration")
            sys.exit(1)
    else:
        print('WAPT silent post-configuration')

    # SELinux rules for CentOS/RedHat
    if type_redhat():
        if re.match('^SELinux status:.*enabled', run('sestatus')):
            if not quiet:
                postconf.msgbox(
                    'SELinux detected, tweaking httpd permissions.')
                selinux_rules()
                postconf.msgbox(
                    'SELinux correctly configured for Nginx reverse proxy')
            else:
                print('[*] Redhat/Centos detected, tweaking SELinux rules')
                selinux_rules()
                print(
                    '[*] Nginx - SELinux correctly configured for Nginx reverse proxy'
                )

    # Load existing config file
    server_config = waptserver.config.load_config(options.configfile)

    if os.path.isfile(options.configfile):
        print('[*] Making a backup copy of the configuration file')
        datetime_now = datetime.datetime.now()
        shutil.copyfile(
            options.configfile,
            '%s.bck_%s' % (options.configfile, datetime_now.isoformat()))

    wapt_folder = server_config['wapt_folder']

    # add secret key initialisation string (for session token)
    if not server_config['secret_key']:
        server_config['secret_key'] = ''.join(
            random.SystemRandom().choice(string.letters + string.digits)
            for _ in range(64))

    # add user db and password in ini file
    if server_config['db_host'] in (None, '', 'localhost', '127.0.0.1', '::1'):
        ensure_postgresql_db(db_name=server_config['db_name'],
                             db_owner=server_config['db_name'],
                             db_password=server_config['db_password'])

    # Password setup/reset screen
    if not quiet:
        if not server_config['wapt_password'] or \
                postconf.yesno("Do you want to reset admin password ?",yes_label='skip',no_label='reset') != postconf.DIALOG_OK:
            wapt_password_ok = False
            while not wapt_password_ok:
                wapt_password = ''
                wapt_password_check = ''

                while wapt_password == '':
                    (code, wapt_password) = postconf.passwordbox(
                        "Please enter the wapt server password (min. 10 characters):  ",
                        insecure=True,
                        width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                while wapt_password_check == '':
                    (code, wapt_password_check) = postconf.passwordbox(
                        "Please enter the wapt server password again:  ",
                        insecure=True,
                        width=100)
                    if code != postconf.DIALOG_OK:
                        exit(0)

                if wapt_password != wapt_password_check:
                    postconf.msgbox('Password mismatch !')
                elif len(wapt_password) < 10:
                    postconf.msgbox(
                        'Password must be at least 10 characters long !')
                else:
                    wapt_password_ok = True

            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password
    else:
        wapt_password = ''
        if not server_config['wapt_password']:
            print('[*] Generating random password for WAPT server')
            wapt_password = pwd.genword(entropy=56, charset="ascii_62")
            print('[*] WAPT admin password : %s' % wapt_password)
            password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
            server_config['wapt_password'] = password

    if not server_config['server_uuid']:
        server_config['server_uuid'] = str(uuid.uuid1())

    # waptagent authentication method
    if not quiet:
        choices = [
            ("1",
             "Allow unauthenticated registration, same behavior as WAPT 1.3",
             True),
            ("2",
             "Enable kerberos authentication required for machines registration",
             False),
            ("3",
             "Disable Kerberos but registration require strong authentication",
             False),
        ]

        code, t = postconf.radiolist("WaptAgent Authentication type?",
                                     choices=choices,
                                     width=120)
        if code == 'cancel':
            print("\n\npostconfiguration canceled\n\n")
            sys.exit(1)
        if t == "1":
            server_config['allow_unauthenticated_registration'] = True
            server_config['use_kerberos'] = False
        if t == "2":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = True
        if t == "3":
            server_config['allow_unauthenticated_registration'] = False
            server_config['use_kerberos'] = False
    else:
        print(
            '[*] Set default registration method to : Allow anyone to register + Kerberos disabled'
        )
        server_config['allow_unauthenticated_registration'] = True
        server_config['use_kerberos'] = False

    # Guess fqdn using socket
    fqdn = guess_fqdn()

    clients_signing_certificate = server_config.get(
        'clients_signing_certificate')
    clients_signing_key = server_config.get('clients_signing_key')
    clients_signing_crl = server_config.get('clients_signing_crl')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir, 'conf',
                                                   'ca-%s.crt' % fqdn)
        clients_signing_key = os.path.join(wapt_root_dir, 'conf',
                                           'ca-%s.pem' % fqdn)

        server_config[
            'clients_signing_certificate'] = clients_signing_certificate
        server_config['clients_signing_key'] = clients_signing_key

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(
            clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn,
                                         is_code_signing=False,
                                         is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    if clients_signing_certificate is not None and clients_signing_key is not None and clients_signing_crl is not None and not os.path.isfile(
            clients_signing_crl):
        print('Create a CRL for clients certificate signing')
        key = SSLPrivateKey(clients_signing_key)
        crt = SSLCertificate(clients_signing_certificate)
        crl = SSLCRL(clients_signing_crl, cacert=crt, cakey=key)
        crl.revoke_cert()
        crl.save_as_pem()

    waptserver.config.write_config_file(cfgfile=options.configfile,
                                        server_config=server_config,
                                        non_default_values_only=True)

    print('[*] Protecting WAPT config file')
    run("/bin/chmod 640 %s" % options.configfile)
    run("/bin/chown wapt %s" % options.configfile)

    print('[*] Update WAPT repository')
    repo = WaptLocalRepo(wapt_folder)
    repo.update_packages_index(force_all=True)

    final_msg = [
        '[*] Postconfiguration completed.',
    ]
    if not quiet:
        postconf.msgbox("Press ok to start waptserver and wapttasks daemons")
    enable_waptserver()
    start_waptserver()

    # In this new version Apache is replaced with Nginx? Proceed to disable Apache. After migration one can remove Apache install altogether
    stop_disable_httpd()

    # Nginx configuration
    if quiet:
        try:
            generate_dhparam()
            nginx_cleanup()
            make_httpd_config('/opt/wapt/waptserver', fqdn,
                              options.force_https, server_config)
            enable_nginx()
            restart_nginx()
            setup_firewall()
        except subprocess.CalledProcessError as cpe:
            final_msg += [
                'Error while trying to configure Nginx!',
                'errno = ' + str(cpe.returncode) + ', output: ' + cpe.output
            ]
        except Exception as e:
            import traceback
            final_msg += [
                'Error while trying to configure Nginx!',
                traceback.format_exc()
            ]
    else:
        reply = postconf.yesno("Do you want to configure nginx?")
        if reply == postconf.DIALOG_OK:
            try:
                msg = 'FQDN for the WAPT server (eg. wapt.acme.com)'
                (code, reply) = postconf.inputbox(text=msg,
                                                  width=len(msg) + 4,
                                                  init=fqdn)
                if code != postconf.DIALOG_OK:
                    exit(1)
                else:
                    fqdn = reply

                generate_dhparam()
                nginx_cleanup()

                if server_config['use_kerberos']:
                    if type_debian():
                        if not check_if_deb_installed(
                                'libnginx-mod-http-auth-spnego'):
                            print(
                                '[*] Nginx - Missing dependency libnginx-mod-http-auth-spnego, please install first before configuring kerberos'
                            )
                            sys.exit(1)

                make_httpd_config('/opt/wapt/waptserver', fqdn,
                                  options.force_https, server_config)
                final_msg.append('Please connect to https://' + fqdn +
                                 '/ to access the server.')
                postconf.msgbox(
                    "The Nginx config is done. We need to restart Nginx?")
                run_verbose('systemctl enable nginx')
                run_verbose('systemctl restart nginx')
                setup_firewall()

            except subprocess.CalledProcessError as cpe:
                final_msg += [
                    'Error while trying to configure Nginx!', 'errno = ' +
                    str(cpe.returncode) + ', output: ' + cpe.output
                ]
            except Exception as e:
                import traceback
                final_msg += [
                    'Error while trying to configure Nginx!',
                    traceback.format_exc()
                ]

    # known certificates
    ssl_dir = server_config['known_certificates_folder']
    if not os.path.isdir(ssl_dir):
        # move existing ssl dir in wapt repo to parent dir (default location)
        if os.path.isdir(os.path.join(server_config['wapt_folder'], 'ssl')):
            shutil.move(os.path.join(server_config['wapt_folder'], 'ssl'),
                        ssl_dir)
        else:
            os.makedirs(ssl_dir)

    #Migrate file for new version waptwua
    wuafolder = server_config['waptwua_folder']
    for (root, dirs, files) in list(os.walk(wuafolder, topdown=False)):
        if root == os.path.join(wuafolder, '.stfolder'):
            continue
        for f in files:
            oldpath = os.path.join(root, f)
            newpath = os.path.join(wuafolder, f)
            if os.path.isfile(newpath):
                continue
            print('Move %s --> %s' % (oldpath, newpath))
            shutil.move(oldpath, newpath)
        for d in dirs:
            if d == '.stfolder':
                continue
            print('Delete folder %s' % os.path.join(root, d))
            shutil.rmtree(os.path.join(root, d))

    final_msg.append('Please connect to https://' + fqdn +
                     '/ to access the server.')

    # Check if Mongodb > PostgreSQL migration is necessary
    if not quiet:
        if check_mongo2pgsql_upgrade_needed(options.configfile) and\
                postconf.yesno("It is necessary to migrate current database backend from mongodb to postgres. Press yes to start migration",no_label='cancel') == postconf.DIALOG_OK:
            upgrade2postgres(options.configfile)
    else:
        if check_mongo2pgsql_upgrade_needed(options.configfile):
            upgrade2postgres(options.configfile)

    WAPT_UID = good_pwd.getpwnam('wapt').pw_uid

    # CHOWN of waptservertasks.sqlite it seems to be created before

    location_waptservertasks = os.path.join(wapt_root_dir, 'db',
                                            'waptservertasks.sqlite')

    if os.path.isfile(location_waptservertasks):
        os.chown(location_waptservertasks, WAPT_UID,
                 os.stat(location_waptservertasks).st_gid)

    # Create empty sync.json and rules.json file for all installations

    sync_json = os.path.join(
        os.path.abspath(os.path.join(wapt_folder, os.pardir)), u'sync.json')
    rules_json = os.path.join(
        os.path.abspath(os.path.join(wapt_folder, os.pardir)), u'rules.json')

    diff_rules_dir = wapt_folder + u'-diff-repos/'

    paths_to_modify = [
        sync_json, rules_json, wapt_folder + '/', wuafolder + '/',
        diff_rules_dir, ssl_dir + '/'
    ]

    for apath in paths_to_modify:
        if os.path.isdir(apath):
            os.chown(apath, WAPT_UID, NGINX_GID)
            os.chmod(apath, 0o750)
            for root, dirs, files in os.walk(apath):
                for d in dirs:
                    full_path = os.path.join(root, d)
                    os.chown(full_path, WAPT_UID, NGINX_GID)
                    os.chmod(full_path, 0o750)
                for f in files:
                    full_path = os.path.join(root, f)
                    os.chown(full_path, WAPT_UID, NGINX_GID)
                    os.chmod(full_path, 0o640)
        else:
            if apath.endswith('/'):
                os.mkdir(apath)
                os.chmod(apath, 0o750)
            else:
                if not (os.path.isfile(apath)):
                    with open(apath, 'w'):
                        pass
                os.chmod(apath, 0o640)
            os.chown(apath, WAPT_UID, NGINX_GID)

    # Final message
    if not quiet:
        width = 4 + max(10, len(max(final_msg, key=len)))
        height = 2 + max(20, len(final_msg))
        postconf.msgbox('\n'.join(final_msg), height=height, width=width)
    else:
        if wapt_password:
            final_msg.append('[*] WAPT admin password : %s\n' % wapt_password)
        for line in final_msg:
            print(line)
Esempio n. 5
0
def main():
    parser=OptionParser(usage=__doc__,prog = 'wapt-signpackage')
    parser.add_option("-c","--certificate", dest="public_key", default='', help="Path to the PEM RSA certificate to embed identitiy in control. (default: %default)")
    parser.add_option("-k","--private-key", dest="private_key", default='', help="Path to the PEM RSA private key to sign packages.  (default: %default)")
    #parser.add_option("-w","--private-key-passwd", dest="private_key_passwd", default='', help="Path to the password of the private key. (default: %default)")
    parser.add_option("-l","--loglevel", dest="loglevel", default=None, type='choice',  choices=['debug','warning','info','error','critical'], metavar='LOGLEVEL',help="Loglevel (default: warning)")
    parser.add_option("-m","--message-digest", dest="md", default='sha256', help="Message digest type for signatures.  (default: %default)")
    parser.add_option("-s","--scan-packages", dest="doscan", default=False, action='store_true', help="Rescan packages and update local Packages index after signing.  (default: %default)")
    parser.add_option("-r","--remove-setup", dest="removesetup", default=False, action='store_true', help="Remove setup.py.  (default: %default)")
    parser.add_option("-i","--inc-release",    dest="increlease",    default=False, action='store_true', help="Increase release number when building package (default: %default)")
    parser.add_option("--maturity", dest="set_maturity", default=None, help="Set/change package maturity when signing package.  (default: None)")
    parser.add_option(     "--keep-signature-date", dest="keep_signature_date",default=False, action='store_true', help="Keep the current package signature date, and file changetime (default: %default)")
    parser.add_option(     "--if-needed", dest="if_needed", default=False, action='store_true',help="Re-sign package only if needed (default: warning)")
    (options,args) = parser.parse_args()

    loglevel = options.loglevel

    if len(logger.handlers) < 1:
        hdlr = logging.StreamHandler(sys.stderr)
        hdlr.setFormatter(logging.Formatter(
            u'%(asctime)s %(levelname)s %(message)s'))
        logger.addHandler(hdlr)

    if loglevel:
        setloglevel(logger,loglevel)
    else:
        setloglevel(logger,'warning')

    if len(args) < 1:
        print(parser.usage)
        sys.exit(1)

    if not options.public_key and not options.private_key:
        print('ERROR: No certificate found or specified')
        sys.exit(1)

    if options.private_key and os.path.isfile(options.private_key):
        key = SSLPrivateKey(options.private_key)
    else:
        cert = SSLCertificate(options.public_key or options.private_key)
        key = cert.matching_key_in_dirs()

    if not key:
        print('ERROR: No private key found or specified')
        sys.exit(1)

    args = ensure_list(args)

    ca_bundle = SSLCABundle()
    signers_bundle = SSLCABundle()
    signers_bundle.add_certificates_from_pem(pem_filename=options.public_key)

    waptpackages = []
    for arg in args:
        waptpackages.extend(glob.glob(arg))

    errors = []
    package_dirs = []
    for waptpackage in waptpackages:
        package_dir = os.path.abspath(os.path.dirname(waptpackage))
        if not package_dir in package_dirs:
            package_dirs.append(package_dir)

        print('Processing %s'%waptpackage)
        try:
            sign_needed=False
            pe = PackageEntry(waptfile = waptpackage)
            if options.removesetup:
                if pe.has_file('setup.py'):
                    with pe.as_zipfile(mode='a') as waptfile:
                        waptfile.remove('setup.py')
                    sign_needed=True

            if not sign_needed and options.if_needed:
                try:
                    pe.check_control_signature(trusted_bundle=signers_bundle,signers_bundle=signers_bundle)
                    for md in ensure_list(options.md):
                        if not pe.has_file(pe.get_signature_filename(md)):
                            raise Exception('Missing signature for md %s' % md)
                    logger.info('Skipping %s, already signed properly' % pe.asrequirement())
                    sign_needed = False
                except Exception as e:
                    logger.info('Sign is needed for %s because %s' % (pe.asrequirement(),e))
                    sign_needed = True

            if options.increlease:
                pe.inc_build()
                sign_needed = True

            if options.set_maturity is not None and pe.maturity != options.set_maturity:
                pe.maturity = options.set_maturity
                sign_needed = True

            if not options.if_needed or sign_needed:
                pe.sign_package(private_key=key,certificate = signers_bundle.certificates(),mds = ensure_list(options.md),keep_signature_date=options.keep_signature_date)
                newfn = pe.make_package_filename()
                if newfn != pe.filename:
                    newfn_path = os.path.join(package_dir,newfn)
                    if not os.path.isfile(newfn_path):
                        print(u"Renaming file from %s to %s to match new package's properties" % (pe.filename,newfn))
                        shutil.move(os.path.join(package_dir,pe.filename),newfn_path)
                    else:
                        print('WARNING: unable to rename file from %s to %s because target already exists' % (pe.filename,newfn))

            print('Done')
        except Exception as e:
            print(u'Error: %s'%ensure_unicode(e.message))
            errors.append([waptpackage,repr(e)])

    if options.doscan:
        for package_dir in package_dirs:
            if os.path.isfile(os.path.join(package_dir,'Packages')):
                print(u'Launching the update of Packages index in %s ...'% ensure_unicode(package_dir))
                repo = WaptLocalRepo(package_dir)
                repo.update_packages_index()
                print('Done')
    else:
        print("Don't forget to rescan your repository with wapt-scanpackages %s" % os.path.dirname(waptpackages[0]))

    if errors:
        print('Package not processed properly: ')
        for fn,error in errors:
            print(u'%s : %s' % (fn,error))

        sys.exit(1)
    else:
        sys.exit(0)
Esempio n. 6
0
def install_waptserver_service(options,conf=None):
    if setuphelpers.service_installed('WAPTServer'):
        if setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_stop('WAPTServer')
        setuphelpers.service_delete('WAPTServer')

    if conf is None:
        conf = waptserver.config.load_config(options.configfile)

    conf_dir =  os.path.join(wapt_root_dir,'conf')
    if not os.path.isdir(conf_dir):
        os.makedirs(conf_dir)
    run(r'icacls "%s" /t /grant  "*S-1-5-20":(OI)(CI)(M)' % conf_dir)

    print("install waptserver")
    service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe'))
    service_parameters = '"%s"' % os.path.join(wapt_root_dir,'waptserver','server.py')
    service_logfile = os.path.join(log_directory, 'nssm_waptserver.log')
    service_dependencies = 'WAPTPostgresql'
    install_windows_nssm_service('WAPTServer',service_binary,service_parameters,service_logfile,service_dependencies)

    tasks_db = os.path.join(wapt_root_dir,'db')
    mkdir_p(tasks_db)
    setuphelpers.run(r'icacls "%s" /grant  "*S-1-5-20":(OI)(CI)(M)' % tasks_db)

    if not conf.get('secret_key'):
        conf['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64))
        waptserver.config.write_config_file(options.configfile,conf)

    if options.setpassword:
        conf['wapt_password'] = pbkdf2_sha256.hash(base64.b64decode(options.setpassword).encode('utf8'))
        waptserver.config.write_config_file(options.configfile,conf)

    clients_signing_certificate =  conf.get('clients_signing_certificate')
    clients_signing_key = conf.get('clients_signing_key')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn())
        clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn())

        conf['clients_signing_certificate'] = clients_signing_certificate
        conf['clients_signing_key'] = clients_signing_key
        waptserver.config.write_config_file(options.configfile,conf)

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn(),is_code_signing=False,is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    # ensure Packages index
    repo = WaptLocalRepo(conf['wapt_folder'])
    repo.update_packages_index()

    if setuphelpers.service_installed('WAPTServer'):
        if not setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_start('WAPTServer')
Esempio n. 7
0
def test_packages():
    repo = WaptLocalRepo('c:/wapt/cache')
    new_packages = Packages.update_from_repo(repo)
    print new_packages
Esempio n. 8
0
def install_waptserver_service(options,conf=None):
    if setuphelpers.service_installed('WAPTServer'):
        if setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_stop('WAPTServer')
        setuphelpers.service_delete('WAPTServer')

    if conf is None:
        conf = waptserver.config.load_config(options.configfile)

    conf_dir =  os.path.join(wapt_root_dir,'conf')
    if not os.path.isdir(conf_dir):
        os.makedirs(conf_dir)
    run(r'icacls "%s" /t /grant  "*S-1-5-20":(OI)(CI)(M)' % conf_dir)

    if not conf.get('server_uuid'):
        conf['server_uuid'] = str(uuid.uuid1())
        waptserver.config.write_config_file(options.configfile,conf)

    print("install waptserver")
    service_binary = os.path.abspath(os.path.join(wapt_root_dir,'waptpython.exe'))
    service_parameters = '"%s"' % os.path.join(wapt_root_dir,'waptserver','server.py')
    service_logfile = os.path.join(log_directory, 'nssm_waptserver.log')
    service_dependencies = 'WAPTPostgresql'
    install_windows_nssm_service('WAPTServer',service_binary,service_parameters,service_logfile,service_dependencies)

    tasks_db = os.path.join(wapt_root_dir,'db')
    mkdir_p(tasks_db)
    setuphelpers.run(r'icacls "%s" /grant  "*S-1-5-20":(OI)(CI)(M)' % tasks_db)

    if not conf.get('secret_key'):
        conf['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64))
        waptserver.config.write_config_file(options.configfile,conf)

    if options.setpassword:
        conf['wapt_password'] = pbkdf2_sha256.hash(base64.b64decode(options.setpassword).encode('utf8'))
        waptserver.config.write_config_file(options.configfile,conf)

    clients_signing_certificate =  conf.get('clients_signing_certificate')
    clients_signing_key = conf.get('clients_signing_key')

    if not clients_signing_certificate or not clients_signing_key:
        clients_signing_certificate = os.path.join(wapt_root_dir,'conf','ca-%s.crt' % fqdn())
        clients_signing_key = os.path.join(wapt_root_dir,'conf','ca-%s.pem' % fqdn())

        conf['clients_signing_certificate'] = clients_signing_certificate
        conf['clients_signing_key'] = clients_signing_key
        waptserver.config.write_config_file(options.configfile,conf)

    if clients_signing_certificate is not None and clients_signing_key is not None and not os.path.isfile(clients_signing_certificate):
        print('Create a certificate and key for clients certificate signing')

        key = SSLPrivateKey(clients_signing_key)
        if not os.path.isfile(clients_signing_key):
            print('Create SSL RSA Key %s' % clients_signing_key)
            key.create()
            key.save_as_pem()

        crt = key.build_sign_certificate(cn=fqdn(),is_code_signing=False,is_ca=True)
        print('Create X509 cert %s' % clients_signing_certificate)
        crt.save_as_pem(clients_signing_certificate)

    # ensure Packages index
    repo = WaptLocalRepo(conf['wapt_folder'])
    repo.update_packages_index()

    #Migrate file for new version waptwua
    wuafolder = conf['waptwua_folder']
    for (root,dirs,files) in list(os.walk(wuafolder,topdown=False)):
        if root == os.path.join(wuafolder,'.stfolder'):
            continue
        for f in files:
            oldpath = os.path.join(root,f)
            newpath = os.path.join(wuafolder,f)
            if os.path.isfile(newpath):
                continue
            print('Move %s --> %s' % (oldpath,newpath))
            os.rename(oldpath,newpath)
        for d in dirs:
            if d == '.stfolder':
                continue
            print('Delete folder %s' % os.path.join(root,d))
            shutil.rmtree(os.path.join(root,d))

    if setuphelpers.service_installed('WAPTServer'):
        if not setuphelpers.service_is_running('WAPTServer'):
            setuphelpers.service_start('WAPTServer')
Esempio n. 9
0
def main():
    global wapt_folder,NGINX_GID


    parser = OptionParser(usage=usage, version=__version__)
    parser.add_option(
        '-c',
        '--config',
        dest='configfile',
        default=waptserver.config.DEFAULT_CONFIG_FILE,
        help='Config file full path (default: %default)')
    parser.add_option(
        "-s",
        "--force-https",
        dest="force_https",
        default=False,
        action='store_true',
        help="Use https only, http is 301 redirected to https (default: False). Requires a proper DNS name")

    (options, args) = parser.parse_args()

    if postconf.yesno("Do you want to launch post configuration tool ?") != postconf.DIALOG_OK:
        print "canceling wapt postconfiguration"
        sys.exit(1)


    # TODO : check if it a new install or an upgrade (upgrade from mongodb to postgresql)

    if type_redhat():
        if re.match('^SELinux status:.*enabled', run('sestatus')):
            postconf.msgbox('SELinux detected, tweaking httpd permissions.')
            run('setsebool -P httpd_can_network_connect 1')
            run('setsebool -P httpd_setrlimit on')
            for sepath in ('wapt','wapt-host'):
                run('semanage fcontext -a -t httpd_sys_content_t "/var/www/html/%s(/.*)?"' %sepath)
                run('restorecon -R -v /var/www/html/%s' %sepath)
            postconf.msgbox('SELinux correctly configured for Nginx reverse proxy')

    server_config = waptserver.config.load_config(options.configfile)

    if os.path.isfile(options.configfile):
        print('making a backup copy of the configuration file')
        datetime_now = datetime.datetime.now()
        shutil.copyfile(options.configfile,'%s.bck_%s'%  (options.configfile,datetime_now.isoformat()) )

    wapt_folder = server_config['wapt_folder']

    # add secret key initialisation string (for session token)
    if not server_config['secret_key']:
        server_config['secret_key'] = ''.join(random.SystemRandom().choice(string.letters + string.digits) for _ in range(64))

    # add user db and password in ini file
    if server_config['db_host'] in (None,'','localhost','127.0.0.1','::1'):
        ensure_postgresql_db(db_name=server_config['db_name'],db_owner=server_config['db_name'],db_password=server_config['db_password'])

    # Password setup/reset screen
    if not server_config['wapt_password'] or \
            postconf.yesno("Do you want to reset admin password ?",yes_label='skip',no_label='reset') != postconf.DIALOG_OK:
        wapt_password_ok = False
        while not wapt_password_ok:
            wapt_password = ''
            wapt_password_check = ''

            while wapt_password == '':
                (code,wapt_password) = postconf.passwordbox("Please enter the wapt server password (min. 10 characters):  ", insecure=True,width=100)
                if code != postconf.DIALOG_OK:
                    exit(0)

            while wapt_password_check == '':
                (code,wapt_password_check) = postconf.passwordbox("Please enter the wapt server password again:  ", insecure=True,width=100)
                if code != postconf.DIALOG_OK:
                    exit(0)

            if wapt_password != wapt_password_check:
                postconf.msgbox('Password mismatch !')
            elif len(wapt_password) < 10:
                postconf.msgbox('Password must be at least 10 characters long !')
            else:
                wapt_password_ok = True

        password = pbkdf2_sha256.hash(wapt_password.encode('utf8'))
        server_config['wapt_password'] = password

    if not server_config['server_uuid']:
        server_config['server_uuid'] = str(uuid.uuid1())


    # waptagent authentication method
    choices = [
            ("1","Allow unauthenticated registration, same behavior as wapt 1.3", True),
            ("2","Enable kerberos authentication required for machines registration", False),
            ("3","Disable Kerberos but registration require strong authentication", False),
            ]

    code, t = postconf.radiolist("WaptAgent Authentication type?", choices=choices,width=120)
    if code=='cancel':
        print("\n\npostconfiguration canceled\n\n")
        sys.exit(1)
    if t=="1":
        server_config['allow_unauthenticated_registration'] = True
        server_config['use_kerberos'] = False
    if t=="2":
        server_config['allow_unauthenticated_registration'] = False
        server_config['use_kerberos'] = True
    if t=="3":
        server_config['allow_unauthenticated_registration'] = False
        server_config['use_kerberos'] = False


    waptserver.config.write_config_file(cfgfile=options.configfile,server_config=server_config,non_default_values_only=True)

    run("/bin/chmod 640 %s" % options.configfile)
    run("/bin/chown wapt %s" % options.configfile)

    repo = WaptLocalRepo(wapt_folder)
    repo.update_packages_index(force_all=True)

    final_msg = ['Postconfiguration completed.',]
    postconf.msgbox("Press ok to start waptserver and wapttasks daemons")
    enable_waptserver()
    start_waptserver()

    # In this new version Apache is replaced with Nginx? Proceed to disable Apache. After migration one can remove Apache install altogether
    try:
        run_verbose('systemctl stop %s' % APACHE_SVC)
    except:
        pass
    try:
        run_verbose('systemctl disable %s' % APACHE_SVC)
    except:
        pass

    # nginx configuration dialog
    reply = postconf.yesno("Do you want to configure nginx?")
    if reply == postconf.DIALOG_OK:
        try:
            fqdn = socket.getfqdn()
            if not fqdn:
                fqdn = 'wapt'
            if '.' not in fqdn:
                fqdn += '.lan'
            msg = 'FQDN for the WAPT server (eg. wapt.acme.com)'
            (code, reply) = postconf.inputbox(text=msg, width=len(msg)+4, init=fqdn)
            if code != postconf.DIALOG_OK:
                exit(1)
            else:
                fqdn = reply

            dh_filename = '/etc/ssl/certs/dhparam.pem'
            if not os.path.exists(dh_filename):
                run_verbose('openssl dhparam -out %s  2048' % dh_filename)

            os.chown(dh_filename, 0, NGINX_GID) #pylint: disable=no-member
            os.chmod(dh_filename, 0o640)        #pylint: disable=no-member

            # cleanup of nginx.conf file
            with open('/etc/nginx/nginx.conf','r') as read_conf:
                nginx_conf = nginxparser.load(read_conf)
            nginx_conf = nginx_set_worker_limit(nginx_conf)
            nginx_conf = nginx_clean_default_vhost(nginx_conf)
            with open("/etc/nginx/nginx.conf", "w") as nginx_conf_file:
                nginx_conf_file.write(nginxparser.dumps(nginx_conf))

            if server_config['use_kerberos']:
                if type_debian():
                    if not check_if_deb_installed('libnginx-mod-http-auth-spnego'):
                        print('missing dependency libnginx-mod-http-auth-spnego, please install first before configuring kerberos')
                        sys.exit(1)

            make_httpd_config(wapt_folder, '/opt/wapt/waptserver', fqdn, server_config['use_kerberos'], options.force_https,server_config['waptserver_port'])

            final_msg.append('Please connect to https://' + fqdn + '/ to access the server.')

            postconf.msgbox("The Nginx config is done. We need to restart Nginx?")
            run_verbose('systemctl enable nginx')
            run_verbose('systemctl restart nginx')
            setup_firewall()

        except subprocess.CalledProcessError as cpe:
            final_msg += [
                'Error while trying to configure Nginx!',
                'errno = ' + str(cpe.returncode) + ', output: ' + cpe.output
                ]
        except Exception as e:
            import traceback
            final_msg += [
            'Error while trying to configure Nginx!',
            traceback.format_exc()
            ]


    if check_mongo2pgsql_upgrade_needed(options.configfile) and\
            postconf.yesno("It is necessary to migrate current database backend from mongodb to postgres. Press yes to start migration",no_label='cancel') == postconf.DIALOG_OK:
        upgrade2postgres(options.configfile)

    width = 4 + max(10, len(max(final_msg, key=len)))
    height = 2 + max(20, len(final_msg))
    postconf.msgbox('\n'.join(final_msg), height=height, width=width)
Esempio n. 10
0
def main():
    parser=OptionParser(usage=__doc__,prog = 'wapt-signpackage')
    parser.add_option("-c","--certificate", dest="public_key", default='', help="Path to the PEM RSA certificate to embed identitiy in control. (default: %default)")
    parser.add_option("-k","--private-key", dest="private_key", default='', help="Path to the PEM RSA private key to sign packages.  (default: %default)")
    #parser.add_option("-w","--private-key-passwd", dest="private_key_passwd", default='', help="Path to the password of the private key. (default: %default)")
    parser.add_option("-l","--loglevel", dest="loglevel", default=None, type='choice',  choices=['debug','warning','info','error','critical'], metavar='LOGLEVEL',help="Loglevel (default: warning)")
    parser.add_option("-m","--message-digest", dest="md", default='sha256', help="Message digest type for signatures.  (default: %default)")
    parser.add_option("-s","--scan-packages", dest="doscan", default=False, action='store_true', help="Rescan packages and update local Packages index after signing.  (default: %default)")
    parser.add_option("-r","--remove-setup", dest="removesetup", default=False, action='store_true', help="Remove setup.py.  (default: %default)")
    parser.add_option("-i","--inc-release",    dest="increlease",    default=False, action='store_true', help="Increase release number when building package (default: %default)")
    parser.add_option("--maturity", dest="set_maturity", default=None, help="Set/change package maturity when signing package.  (default: None)")
    parser.add_option(     "--keep-signature-date", dest="keep_signature_date",default=False, action='store_true', help="Keep the current package signature date, and file changetime (default: %default)")
    parser.add_option(     "--if-needed", dest="if_needed", default=False, action='store_true',help="Re-sign package only if needed (default: warning)")
    (options,args) = parser.parse_args()

    loglevel = options.loglevel

    if len(logger.handlers) < 1:
        hdlr = logging.StreamHandler(sys.stderr)
        hdlr.setFormatter(logging.Formatter(
            u'%(asctime)s %(levelname)s %(message)s'))
        logger.addHandler(hdlr)

    if loglevel:
        setloglevel(logger,loglevel)
    else:
        setloglevel(logger,'warning')

    if len(args) < 1:
        print(parser.usage)
        sys.exit(1)

    if not options.public_key and not options.private_key:
        print('ERROR: No certificate found or specified')
        sys.exit(1)

    if options.private_key and os.path.isfile(options.private_key):
        key = SSLPrivateKey(options.private_key)
    else:
        cert = SSLCertificate(options.public_key or options.private_key)
        key = cert.matching_key_in_dirs()

    if not key:
        print('ERROR: No private key found or specified')
        sys.exit(1)

    args = ensure_list(args)

    ca_bundle = SSLCABundle()
    signers_bundle = SSLCABundle()
    signers_bundle.add_certificates_from_pem(pem_filename=options.public_key)

    waptpackages = []
    for arg in args:
        waptpackages.extend(glob.glob(arg))

    errors = []
    package_dirs = []
    for waptpackage in waptpackages:
        package_dir = os.path.abspath(os.path.dirname(waptpackage))
        if not package_dir in package_dirs:
            package_dirs.append(package_dir)

        print('Processing %s'%waptpackage)
        try:
            sign_needed=False
            pe = PackageEntry(waptfile = waptpackage)
            if options.removesetup:
                if pe.has_file('setup.py'):
                    with pe.as_zipfile(mode='a') as waptfile:
                        waptfile.remove('setup.py')
                    sign_needed=True

            if not sign_needed and options.if_needed:
                try:
                    pe.check_control_signature(trusted_bundle=signers_bundle,signers_bundle=signers_bundle)
                    for md in ensure_list(options.md):
                        if not pe.has_file(pe.get_signature_filename(md)):
                            raise Exception('Missing signature for md %s' % md)
                    logger.info('Skipping %s, already signed properly' % pe.asrequirement())
                    sign_needed = False
                except Exception as e:
                    logger.info('Sign is needed for %s because %s' % (pe.asrequirement(),e))
                    sign_needed = True

            if options.increlease:
                pe.inc_build()
                sign_needed = True

            if options.set_maturity is not None and pe.maturity != options.set_maturity:
                pe.maturity = options.set_maturity
                sign_needed = True

            if not options.if_needed or sign_needed:
                pe.sign_package(private_key=key,certificate = signers_bundle.certificates(),mds = ensure_list(options.md),keep_signature_date=options.keep_signature_date)
                newfn = pe.make_package_filename()
                if newfn != pe.filename:
                    newfn_path = os.path.join(package_dir,newfn)
                    if not os.path.isfile(newfn_path):
                        print(u"Renaming file from %s to %s to match new package's properties" % (pe.filename,newfn))
                        os.rename(os.path.join(package_dir,pe.filename),newfn_path)
                    else:
                        print('WARNING: unable to rename file from %s to %s because target already exists' % (pe.filename,newfn))

            print('Done')
        except Exception as e:
            print(u'Error: %s'%ensure_unicode(e.message))
            errors.append([waptpackage,repr(e)])

    if options.doscan:
        for package_dir in package_dirs:
            if os.path.isfile(os.path.join(package_dir,'Packages')):
                print(u'Launching the update of Packages index in %s ...'% ensure_unicode(package_dir))
                repo = WaptLocalRepo(package_dir)
                repo.update_packages_index()
                print('Done')
    else:
        print("Don't forget to rescan your repository with wapt-scanpackages %s" % os.path.dirname(waptpackages[0]))

    if errors:
        print('Package not processed properly: ')
        for fn,error in errors:
            print(u'%s : %s' % (fn,error))

        sys.exit(1)
    else:
        sys.exit(0)
Esempio n. 11
0
def update_packages_table(conf, wapt_path):
    load_db_config(conf)
    repo = WaptLocalRepo(wapt_path)
    return Packages.update_from_repo(repo)