def get_private_key_encrypted(certificate_path, password=None): """Load certificate and finc matching Key in same dir. Return path to private_key if key is encrypted Args: certificate_path (str): path to personal certificate Returns str: path to matching private key """ cert = SSLCertificate(certificate_path) if isinstance(password, unicode): password = password.encode('utf8') try: if password is None or password == '': key = cert.matching_key_in_dirs( password_callback=NOPASSWORD_CALLBACK, private_key_password=None) else: key = cert.matching_key_in_dirs(private_key_password=password) if key: return key.private_key_filename else: return '' except Exception as e: print(e) return ''
def get_private_key_encrypted(certificate_path,password=None): """Load certificate and finc matching Key in same dir. Return path to private_key if key is encrypted Args: certificate_path (str): path to personal certificate Returns str: path to matching private key """ cert = SSLCertificate(certificate_path) if isinstance(password,unicode): password = password.encode('utf8') try: if password is None or password == '': key = cert.matching_key_in_dirs(password_callback=NOPASSWORD_CALLBACK,private_key_password = None) else: key = cert.matching_key_in_dirs(private_key_password = password) if key: return key.private_key_filename else: return '' except Exception as e: print(e) return ''
def overwrite_signature(pkg): """Overwrite imported package signature""" cert_file = os.environ.get('WAPT_CERT') key_file = os.environ.get('WAPT_KEY') password = os.environ.get('WAPT_PASSWD') if not (cert_file and key_file and password): return False crt = SSLCertificate(cert_file) key = SSLPrivateKey(key_file, password=password) # Force unzip and rebuild to ensure filelist integrity previous_localpath = unpack(pkg) repack(pkg, previous_localpath) return pkg.sign_package(certificate=crt, private_key=key)
def resign_crl(): """Check validity of CRL and resign it if it will expire before next round. """ if (conf['clients_signing_key'] and conf['clients_signing_certificate'] and conf['clients_signing_crl'] and \ os.path.isfile(conf['clients_signing_key']) and os.path.isfile(conf['clients_signing_certificate'])): signing_key = SSLPrivateKey(conf['clients_signing_key']) signing_cert = SSLCertificate(conf['clients_signing_certificate']) server_ca = SSLCABundle(conf['clients_signing_certificate']) logger.info('Resigning CRL %s' % conf['clients_signing_crl']) try: crl = SSLCRL(conf['clients_signing_crl'], cakey=signing_key, cacert=signing_cert) if not crl.crl or crl.next_update <= datetime.datetime.utcnow( ) + datetime.timedelta(hours=1): crl.revoke_cert(crl_ttl_days=conf['clients_signing_crl_days']) crl.save_as_pem() except Exception as e: logger.warning('Unable to sign CRL %s: %s' % (conf['clients_signing_crl'], repr(e)))
def make_nginx_config(wapt_root_dir, wapt_folder, force=False): """Create a nginx default config file to server wapt_folder and reverse proxy waptserver Create a key and self signed certificate. Args: wapt_root_dir (str) wapt_folder (str) : local path to wapt rdirectory for packages wapt-host and waptwua are derived from this. Returns: str: path to nginx conf file """ ap_conf_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'conf') ap_file_name = 'nginx.conf' ap_conf_file = os.path.join(ap_conf_dir, ap_file_name) ap_ssl_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'ssl') if os.path.isfile(ap_conf_file) and not force: if 'waptserver' in open(ap_conf_file, 'r').read(): return ap_conf_file setuphelpers.mkdirs(ap_ssl_dir) key_fn = os.path.join(ap_ssl_dir, 'key.pem') key = SSLPrivateKey(key_fn) if not os.path.isfile(key_fn): print('Create SSL RSA Key %s' % key_fn) key.create() key.save_as_pem() cert_fn = os.path.join(ap_ssl_dir, 'cert.pem') if os.path.isfile(cert_fn): crt = SSLCertificate(cert_fn) if crt.cn != fqdn(): os.rename( cert_fn, "%s-%s.old" % (cert_fn, '{:%Y%m%d-%Hh%Mm%Ss}'.format( datetime.datetime.now()))) crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False) print('Create X509 cert %s' % cert_fn) crt.save_as_pem(cert_fn) else: crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False) print('Create X509 cert %s' % cert_fn) crt.save_as_pem(cert_fn) # write config file jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader( os.path.join(wapt_root_dir, 'waptserver', 'scripts'))) template = jinja_env.get_template('waptwindows.nginxconfig.j2') template_variables = { 'wapt_repository_path': os.path.dirname(conf['wapt_folder']).replace('\\', '/'), 'waptserver_port': conf['waptserver_port'], 'windows': True, 'ssl': True, 'force_https': False, 'use_kerberos': False, 'wapt_ssl_key_file': key_fn.replace('\\', '/'), 'wapt_ssl_cert_file': cert_fn.replace('\\', '/'), 'log_dir': os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'logs').replace('\\', '/'), 'wapt_root_dir': wapt_root_dir.replace('\\', '/'), 'nginx_http': conf['nginx_http'], 'nginx_https': conf['nginx_https'] } config_string = template.render(template_variables) print('Create nginx conf file %s' % ap_conf_file) with open(ap_conf_file, 'wt') as dst_file: dst_file.write(config_string) return ap_conf_file
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)
def make_httpd_config(waptserver_root_dir, fqdn, force_https, server_config): ssl_dir = os.path.join(waptserver_root_dir, 'ssl') scripts_dir = os.path.join(waptserver_root_dir, 'scripts') wapt_ssl_key_file = os.path.join(ssl_dir, 'key.pem') wapt_ssl_cert_file = os.path.join(ssl_dir, 'cert.pem') mkdir(ssl_dir) # write the apache configuration fragment jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(scripts_dir)) template = jinja_env.get_template('wapt.nginxconfig.template') krb5_realm = '.'.join(fqdn.split('.')[1:]).upper() template_vars = { 'waptserver_port': server_config['waptserver_port'], 'wapt_repository_path': os.path.dirname(server_config['wapt_folder']), 'windows': False, 'debian': type_debian(), 'redhat': type_redhat(), 'force_https': force_https, 'wapt_ssl_key_file': wapt_ssl_key_file, 'wapt_ssl_cert_file': wapt_ssl_cert_file, 'fqdn': fqdn, 'use_kerberos': server_config.get('use_kerberos', False), 'KRB5_REALM': krb5_realm, 'wapt_root_dir': wapt_root_dir, 'use_ssl_client_auth': server_config.get('use_ssl_client_auth', False), 'clients_signing_certificate': server_config.get('clients_signing_certificate'), 'known_certificates_folder': server_config.get('known_certificates_folder', None), 'clients_signing_crl': server_config.get('clients_signing_crl', None), 'htpasswd_path': server_config.get('htpasswd_path', None), } if quiet: print('[*] Nginx - creating wapt.conf virtualhost') config_string = template.render(template_vars) if type_debian(): dst_file = file('/etc/nginx/sites-available/wapt.conf', 'wt') if not os.path.exists('/etc/nginx/sites-enabled/wapt.conf'): print( subprocess.check_output( 'ln -s /etc/nginx/sites-available/wapt.conf /etc/nginx/sites-enabled/wapt.conf', shell=True)) if os.path.exists('/etc/nginx/sites-enabled/default'): os.unlink('/etc/nginx/sites-enabled/default') elif type_redhat(): dst_file = file('/etc/nginx/conf.d/wapt.conf', 'wt') dst_file.write(config_string) dst_file.close() # create keys for https:// access if not os.path.exists(wapt_ssl_key_file) or \ not os.path.exists(wapt_ssl_cert_file): if quiet: print('[*] Nginx - generate self-signed certs') old_apache_key = '/opt/wapt/waptserver/apache/ssl/key.pem' old_apache_cert = '/opt/wapt/waptserver/apache/ssl/cert.pem' if os.path.isfile(old_apache_cert) and os.path.isfile(old_apache_key): shutil.copyfile(old_apache_cert, wapt_ssl_cert_file) shutil.copyfile(old_apache_key, wapt_ssl_key_file) else: key = SSLPrivateKey(wapt_ssl_key_file) if not os.path.isfile(wapt_ssl_key_file): print('Create SSL RSA Key %s' % wapt_ssl_key_file) key.create() key.save_as_pem() if os.path.isfile(wapt_ssl_cert_file): crt = SSLCertificate(wapt_ssl_cert_file) if crt.cn != fqdn: shutil.move( wapt_ssl_cert_file, "%s-%s.old" % (wapt_ssl_cert_file, '{:%Y%m%d-%Hh%Mm%Ss}'.format( datetime.datetime.now()))) crt = key.build_sign_certificate(cn=fqdn, dnsname=fqdn, is_code_signing=False) print('Create X509 cert %s' % wapt_ssl_cert_file) crt.save_as_pem(wapt_ssl_cert_file) else: crt = key.build_sign_certificate(cn=fqdn, dnsname=fqdn, is_code_signing=False) print('Create X509 cert %s' % wapt_ssl_cert_file) crt.save_as_pem(wapt_ssl_cert_file) else: if quiet: print('[*] Nginx - self-signed certs already exists, skipping...')
def make_httpd_config(waptserver_root_dir, fqdn, force_https, server_config): ssl_dir = os.path.join(waptserver_root_dir, 'ssl') scripts_dir = os.path.join(waptserver_root_dir, 'scripts') wapt_ssl_key_file = os.path.join(ssl_dir,'key.pem') wapt_ssl_cert_file = os.path.join(ssl_dir,'cert.pem') mkdir(ssl_dir) # write the apache configuration fragment jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(scripts_dir)) template = jinja_env.get_template('wapt.nginxconfig.template') krb5_realm = '.'.join(fqdn.split('.')[1:]).upper() template_vars = { 'waptserver_port': server_config['waptserver_port'], 'wapt_repository_path': os.path.dirname(server_config['wapt_folder']), 'windows': False, 'debian': type_debian(), 'redhat': type_redhat(), 'force_https': force_https, 'wapt_ssl_key_file': wapt_ssl_key_file, 'wapt_ssl_cert_file': wapt_ssl_cert_file, 'fqdn': fqdn, 'use_kerberos': server_config.get('use_kerberos',False), 'KRB5_REALM': krb5_realm, 'wapt_root_dir': wapt_root_dir, 'clients_signing_certificate' : server_config.get('clients_signing_certificate'), 'use_ssl_client_auth' : server_config.get('use_ssl_client_auth',False) } if quiet: print('[*] Nginx - creating wapt.conf virtualhost') config_string = template.render(template_vars) if type_debian(): dst_file = file('/etc/nginx/sites-available/wapt.conf', 'wt') if not os.path.exists('/etc/nginx/sites-enabled/wapt.conf'): print(subprocess.check_output('ln -s /etc/nginx/sites-available/wapt.conf /etc/nginx/sites-enabled/wapt.conf',shell=True)) if os.path.exists('/etc/nginx/sites-enabled/default'): os.unlink('/etc/nginx/sites-enabled/default') elif type_redhat(): dst_file = file('/etc/nginx/conf.d/wapt.conf', 'wt') dst_file.write(config_string) dst_file.close() # create keys for https:// access if not os.path.exists(wapt_ssl_key_file) or \ not os.path.exists(wapt_ssl_cert_file): if quiet: print('[*] Nginx - generate self-signed certs') old_apache_key = '/opt/wapt/waptserver/apache/ssl/key.pem' old_apache_cert = '/opt/wapt/waptserver/apache/ssl/cert.pem' if os.path.isfile(old_apache_cert) and os.path.isfile(old_apache_key): shutil.copyfile(old_apache_cert,wapt_ssl_cert_file) shutil.copyfile(old_apache_key,wapt_ssl_key_file) else: key = SSLPrivateKey(wapt_ssl_key_file) if not os.path.isfile(wapt_ssl_key_file): print('Create SSL RSA Key %s' % wapt_ssl_key_file) key.create() key.save_as_pem() if os.path.isfile(wapt_ssl_cert_file): crt = SSLCertificate(wapt_ssl_cert_file) if crt.cn != fqdn: os.rename(wapt_ssl_cert_file,"%s-%s.old" % (wapt_ssl_cert_file,'{:%Y%m%d-%Hh%Mm%Ss}'.format(datetime.datetime.now()))) crt = key.build_sign_certificate(cn=fqdn,dnsname=fqdn,is_code_signing=False) print('Create X509 cert %s' % wapt_ssl_cert_file) crt.save_as_pem(wapt_ssl_cert_file) else: crt = key.build_sign_certificate(cn=fqdn,dnsname=fqdn,is_code_signing=False) print('Create X509 cert %s' % wapt_ssl_cert_file) crt.save_as_pem(wapt_ssl_cert_file) else: if quiet: print('[*] Nginx - self-signed certs already exists, skipping...')
def make_nginx_config(wapt_root_dir, wapt_folder, force = False): """Create a nginx default config file to server wapt_folder and reverse proxy waptserver Create a key and self signed certificate. Args: wapt_root_dir (str) wapt_folder (str) : local path to wapt rdirectory for packages wapt-host and waptwua are derived from this. Returns: str: path to nginx conf file """ ap_conf_dir = os.path.join( wapt_root_dir, 'waptserver', 'nginx', 'conf') ap_file_name = 'nginx.conf' ap_conf_file = os.path.join(ap_conf_dir, ap_file_name) ap_ssl_dir = os.path.join(wapt_root_dir,'waptserver','nginx','ssl') if os.path.isfile(ap_conf_file) and not force: if 'waptserver' in open(ap_conf_file,'r').read(): return ap_conf_file setuphelpers.mkdirs(ap_ssl_dir) key_fn = os.path.join(ap_ssl_dir,'key.pem') key = SSLPrivateKey(key_fn) if not os.path.isfile(key_fn): print('Create SSL RSA Key %s' % key_fn) key.create() key.save_as_pem() cert_fn = os.path.join(ap_ssl_dir,'cert.pem') if os.path.isfile(cert_fn): crt = SSLCertificate(cert_fn) if crt.cn != fqdn(): os.rename(cert_fn,"%s-%s.old" % (cert_fn,'{:%Y%m%d-%Hh%Mm%Ss}'.format(datetime.datetime.now()))) crt = key.build_sign_certificate(cn=fqdn(),dnsname=fqdn(),is_code_signing=False) print('Create X509 cert %s' % cert_fn) crt.save_as_pem(cert_fn) else: crt = key.build_sign_certificate(cn=fqdn(),dnsname=fqdn(),is_code_signing=False) print('Create X509 cert %s' % cert_fn) crt.save_as_pem(cert_fn) # write config file jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.join(wapt_root_dir,'waptserver','scripts'))) template = jinja_env.get_template('waptwindows.nginxconfig.j2') template_variables = { 'wapt_repository_path': os.path.dirname(conf['wapt_folder']).replace('\\','/'), 'waptserver_port': conf['waptserver_port'], 'windows': True, 'ssl': True, 'force_https': False, 'use_kerberos': False, 'wapt_ssl_key_file': key_fn.replace('\\','/'), 'wapt_ssl_cert_file': cert_fn.replace('\\','/'), 'log_dir': os.path.join(wapt_root_dir,'waptserver','nginx','logs').replace('\\','/'), 'wapt_root_dir' : wapt_root_dir.replace('\\','/'), 'nginx_http' : conf['nginx_http'], 'nginx_https' : conf['nginx_https'], 'clients_signing_certificate' : conf.get('clients_signing_certificate') and conf.get('clients_signing_certificate').replace('\\','/'), 'use_ssl_client_auth' : conf.get('use_ssl_client_auth',False) } config_string = template.render(template_variables) print('Create nginx conf file %s' % ap_conf_file) with open(ap_conf_file, 'wt') as dst_file: dst_file.write(config_string) return ap_conf_file
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)
def make_nginx_config(wapt_root_dir, wapt_folder): if conf['wapt_folder'].endswith('\\') or conf['wapt_folder'].endswith('/'): conf['wapt_folder'] = conf['wapt_folder'][:-1] ap_conf_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'conf') ap_file_name = 'nginx.conf' ap_conf_file = os.path.join(ap_conf_dir, ap_file_name) ap_ssl_dir = os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'ssl') setuphelpers.mkdirs(ap_ssl_dir) key_fn = os.path.join(ap_ssl_dir, 'key.pem') key = SSLPrivateKey(key_fn) if not os.path.isfile(key_fn): print('Create SSL RSA Key %s' % key_fn) key.create() key.save_as_pem() cert_fn = os.path.join(ap_ssl_dir, 'cert.pem') if os.path.isfile(cert_fn): crt = SSLCertificate(cert_fn) if crt.cn != fqdn(): os.rename( cert_fn, "%s-%s.old" % (cert_fn, '{:%Y%m%d-%Hh%Mm%Ss}'.format( datetime.datetime.now()))) crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False) print('Create X509 cert %s' % cert_fn) crt.save_as_pem(cert_fn) else: crt = key.build_sign_certificate(cn=fqdn(), is_code_signing=False) print('Create X509 cert %s' % cert_fn) crt.save_as_pem(cert_fn) # write config file jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader( os.path.join(wapt_root_dir, 'waptserver', 'scripts'))) template = jinja_env.get_template('waptwindows.nginxconfig.j2') template_variables = { 'wapt_repository_path': os.path.dirname(conf['wapt_folder']).replace('\\', '/'), 'windows': True, 'ssl': True, 'force_https': False, 'use_kerberos': False, 'wapt_ssl_key_file': key_fn.replace('\\', '/'), 'wapt_ssl_cert_file': cert_fn.replace('\\', '/'), 'log_dir': os.path.join(wapt_root_dir, 'waptserver', 'nginx', 'logs').replace('\\', '/'), 'wapt_root_dir': wapt_root_dir.replace('\\', '/'), } config_string = template.render(template_variables) print('Create nginx conf file %s' % ap_conf_file) with open(ap_conf_file, 'wt') as dst_file: dst_file.write(config_string)
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)
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') clients_signing_crl = conf.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()) 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) # known certificates ssl_dir = conf['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(conf['wapt_folder'], 'ssl')): shutil.move(os.path.join(conf['wapt_folder'], 'ssl'), ssl_dir) else: os.makedirs(ssl_dir) run(r'icacls "%s" /grant "*S-1-5-20":(OI)(CI)(M)' % ssl_dir) 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() # ensure Packages index crl.save_as_pem() 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)) 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)) if setuphelpers.service_installed('WAPTServer'): if not setuphelpers.service_is_running('WAPTServer'): setuphelpers.service_start('WAPTServer')