def post(self): """ .. http:post:: /auth/login Login with username:password **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "username": "******", "password": "******" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "token": "12343243243" } :arg username: username :arg password: password :statuscode 401: invalid credentials :statuscode 200: no error """ self.reqparse.add_argument('username', type=str, required=True, location='json') self.reqparse.add_argument('password', type=str, required=True, location='json') args = self.reqparse.parse_args() if '@' in args['username']: user = user_service.get_by_email(args['username']) else: user = user_service.get_by_username(args['username']) if user and user.check_password(args['password']): # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) metrics.send('successful_login', 'counter', 1) return dict(token=create_token(user)) metrics.send('invalid_login', 'counter', 1) return dict(message='The supplied credentials are invalid'), 401
def run(self, name, users, description): user_objs = [] for u in users: user_obj = user_service.get_by_username(u) if user_obj: user_objs.append(user_obj) else: sys.stderr.write("[!] Cannot find user {0}".format(u)) sys.exit(1) role_service.create(name, description=description, users=users) sys.stdout.write("[+] Created new role: {0}".format(name))
def run(self, password): create() user = user_service.get_by_username("lemur") if not user: if not password: sys.stdout.write("We need to set Lemur's password to continue!\n") password = prompt_pass("Password") password1 = prompt_pass("Confirm Password") if password != password1: sys.stderr.write("[!] Passwords do not match!\n") sys.exit(1) role = role_service.get_by_name("admin") if role: sys.stdout.write("[-] Admin role already created, skipping...!\n") else: # we create an admin role role = role_service.create("admin", description="this is the lemur administrator role") sys.stdout.write("[+] Created 'admin' role\n") user_service.create("lemur", password, "lemur@nobody", True, None, [role]) sys.stdout.write("[+] Added a 'lemur' user and added it to the 'admin' role!\n") else: sys.stdout.write("[-] Default user has already been created, skipping...!\n") sys.stdout.write("[+] Creating expiration email notifications!\n") sys.stdout.write( "[!] Using {0} as specified by LEMUR_SECURITY_TEAM_EMAIL for notifications\n".format( "LEMUR_SECURITY_TEAM_EMAIL" ) ) intervals = current_app.config.get("LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS", []) sys.stdout.write( "[!] Creating {num} notifications for {intervals} days as specified by LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS\n".format( num=len(intervals), intervals=",".join([str(x) for x in intervals]) ) ) recipients = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL") notification_service.create_default_expiration_notifications("DEFAULT_SECURITY", recipients=recipients) sys.stdout.write("[/] Done!\n")
def run(self, username): user = user_service.get_by_username(username) if not user: sys.stderr.write("[!] No user found for username: {0}\n".format(username)) sys.exit(1) sys.stderr.write("[+] Resetting password for {0}\n".format(username)) password1 = prompt_pass("Password") password2 = prompt_pass("Confirm Password") if password1 != password2: sys.stderr.write("[!] Passwords do not match\n") sys.exit(1) user.password = password1 user.hash_password() database.commit()
def run(self, username): user = user_service.get_by_username(username) if not user: sys.stderr.write( "[!] No user found for username: {0}\n".format(username)) sys.exit(1) sys.stderr.write("[+] Resetting password for {0}\n".format(username)) password1 = prompt_pass("Password") password2 = prompt_pass("Confirm Password") if password1 != password2: sys.stderr.write("[!] Passwords do not match\n") sys.exit(1) user.password = password1 user.hash_password() database.commit()
def sync(source_strings): sources = validate_sources(source_strings) for source in sources: status = FAILURE_METRIC_STATUS start_time = time.time() print("[+] Staring to sync source: {label}!\n".format(label=source.label)) user = user_service.get_by_username('lemur') try: data = source_service.sync(source, user) print( "[+] Certificates: New: {new} Updated: {updated}".format( new=data['certificates'][0], updated=data['certificates'][1] ) ) print( "[+] Endpoints: New: {new} Updated: {updated}".format( new=data['endpoints'][0], updated=data['endpoints'][1] ) ) print( "[+] Finished syncing source: {label}. Run Time: {time}".format( label=source.label, time=(time.time() - start_time) ) ) status = SUCCESS_METRIC_STATUS except Exception as e: current_app.logger.exception(e) print( "[X] Failed syncing source {label}!\n".format(label=source.label) ) sentry.captureException() metrics.send('source_sync_fail', 'counter', 1, metric_tags={'source': source.label, 'status': status}) metrics.send('source_sync', 'counter', 1, metric_tags={'source': source.label, 'status': status})
def sync(source_strings): sources = validate_sources(source_strings) for source in sources: status = FAILURE_METRIC_STATUS start_time = time.time() print("[+] Staring to sync source: {label}!\n".format( label=source.label)) user = user_service.get_by_username('lemur') try: data = source_service.sync(source, user) print("[+] Certificates: New: {new} Updated: {updated}".format( new=data['certificates'][0], updated=data['certificates'][1])) print("[+] Endpoints: New: {new} Updated: {updated}".format( new=data['endpoints'][0], updated=data['endpoints'][1])) print("[+] Finished syncing source: {label}. Run Time: {time}". format(label=source.label, time=(time.time() - start_time))) status = SUCCESS_METRIC_STATUS except Exception as e: current_app.logger.exception(e) print("[X] Failed syncing source {label}!\n".format( label=source.label)) sentry.captureException() metrics.send('source_sync_fail', 'counter', 1, metric_tags={ 'source': source.label, 'status': status }) metrics.send('source_sync', 'counter', 1, metric_tags={ 'source': source.label, 'status': status })
def sync(source_strings): source_objs = validate_sources(source_strings) for source in source_objs: start_time = time.time() print("[+] Staring to sync source: {label}!\n".format( label=source.label)) user = user_service.get_by_username('lemur') try: source_service.sync(source, user) print("[+] Finished syncing source: {label}. Run Time: {time}". format(label=source.label, time=(time.time() - start_time))) except Exception as e: current_app.logger.exception(e) print("[X] Failed syncing source {label}!\n".format( label=source.label)) metrics.send('sync_failed', 'counter', 1, metric_tags={'source': source.label})
def sync_source(source_label): """ This celery task will sync the specified source. :param source: :return: """ function = f"{__name__}.{sys._getframe().f_code.co_name}" logger = logging.getLogger(function) task_id = None if celery.current_task: task_id = celery.current_task.request.id log_data = { "source": source_label, "task_id": task_id, } if task_id and is_task_active(function, task_id, (source_label, )): logger.debug("Skipping task: Task is already active", extra=log_data) return logger.info("Starting syncing source", extra=log_data) user = user_service.get_by_username("lemur") source = source_service.get_by_label(source_label) if not source: raise RuntimeError(f"Source {source_label} not found") result = source_service.sync(source, user) log_data["result"] = result logger.info("Done syncing source", extra=log_data) return
def run(self, password): create() user = user_service.get_by_username("lemur") admin_role = role_service.get_by_name('admin') if admin_role: sys.stdout.write("[-] Admin role already created, skipping...!\n") else: # we create an admin role admin_role = role_service.create( 'admin', description='This is the Lemur administrator role.') sys.stdout.write("[+] Created 'admin' role\n") operator_role = role_service.get_by_name('operator') if operator_role: sys.stdout.write( "[-] Operator role already created, skipping...!\n") else: # we create an admin role operator_role = role_service.create( 'operator', description='This is the Lemur operator role.') sys.stdout.write("[+] Created 'operator' role\n") read_only_role = role_service.get_by_name('read-only') if read_only_role: sys.stdout.write( "[-] Operator role already created, skipping...!\n") else: # we create an admin role read_only_role = role_service.create( 'read-only', description='This is the Lemur read only role.') sys.stdout.write("[+] Created 'read-only' role\n") if not user: if not password: sys.stdout.write( "We need to set Lemur's password to continue!\n") password = prompt_pass("Password") password1 = prompt_pass("Confirm Password") if password != password1: sys.stderr.write("[!] Passwords do not match!\n") sys.exit(1) user_service.create("lemur", password, 'lemur@nobody', True, None, [admin_role]) sys.stdout.write( "[+] Created the user 'lemur' and granted it the 'admin' role!\n" ) else: sys.stdout.write( "[-] Default user has already been created, skipping...!\n") sys.stdout.write("[+] Creating expiration email notifications!\n") sys.stdout.write( "[!] Using {0} as specified by LEMUR_SECURITY_TEAM_EMAIL for notifications\n" .format("LEMUR_SECURITY_TEAM_EMAIL")) intervals = current_app.config.get( "LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS", []) sys.stdout.write( "[!] Creating {num} notifications for {intervals} days as specified by LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS\n" .format(num=len(intervals), intervals=",".join([str(x) for x in intervals]))) recipients = current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL') notification_service.create_default_expiration_notifications( "DEFAULT_SECURITY", recipients=recipients) sys.stdout.write("[/] Done!\n")
def run(self, password): create() user = user_service.get_by_username("lemur") admin_role = role_service.get_by_name("admin") if admin_role: sys.stdout.write("[-] Admin role already created, skipping...!\n") else: # we create an admin role admin_role = role_service.create( "admin", description="This is the Lemur administrator role.") sys.stdout.write("[+] Created 'admin' role\n") operator_role = role_service.get_by_name("operator") if operator_role: sys.stdout.write( "[-] Operator role already created, skipping...!\n") else: # we create an operator role operator_role = role_service.create( "operator", description="This is the Lemur operator role.") sys.stdout.write("[+] Created 'operator' role\n") read_only_role = role_service.get_by_name("read-only") if read_only_role: sys.stdout.write( "[-] Read only role already created, skipping...!\n") else: # we create an read only role read_only_role = role_service.create( "read-only", description="This is the Lemur read only role.") sys.stdout.write("[+] Created 'read-only' role\n") if not user: if not password: sys.stdout.write( "We need to set Lemur's password to continue!\n") password = prompt_pass("Password") password1 = prompt_pass("Confirm Password") if password != password1: sys.stderr.write("[!] Passwords do not match!\n") sys.exit(1) user_service.create("lemur", password, "*****@*****.**", True, None, [admin_role]) sys.stdout.write( "[+] Created the user 'lemur' and granted it the 'admin' role!\n" ) else: sys.stdout.write( "[-] Default user has already been created, skipping...!\n") intervals = current_app.config.get( "LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS", []) sys.stdout.write( "[!] Creating {num} notifications for {intervals} days as specified by LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS\n" .format(num=len(intervals), intervals=",".join([str(x) for x in intervals]))) recipients = current_app.config.get("LEMUR_SECURITY_TEAM_EMAIL") sys.stdout.write("[+] Creating expiration email notifications!\n") sys.stdout.write( "[!] Using {0} as specified by LEMUR_SECURITY_TEAM_EMAIL for notifications\n" .format(recipients)) notification_service.create_default_expiration_notifications( "DEFAULT_SECURITY", recipients=recipients) _DEFAULT_ROTATION_INTERVAL = "default" default_rotation_interval = policy_service.get_by_name( _DEFAULT_ROTATION_INTERVAL) if default_rotation_interval: sys.stdout.write( "[-] Default rotation interval policy already created, skipping...!\n" ) else: days = current_app.config.get("LEMUR_DEFAULT_ROTATION_INTERVAL", 30) sys.stdout.write( "[+] Creating default certificate rotation policy of {days} days before issuance.\n" .format(days=days)) policy_service.create(days=days, name=_DEFAULT_ROTATION_INTERVAL) sys.stdout.write("[/] Done!\n")
def post(self): """ .. http:post:: /auth/login Login with username:password **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript Content-Type: application/json;charset=UTF-8 { "username": "******", "password": "******" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "token": "12343243243" } :arg username: username :arg password: password :statuscode 401: invalid credentials :statuscode 200: no error """ self.reqparse.add_argument("username", type=str, required=True, location="json") self.reqparse.add_argument("password", type=str, required=True, location="json") args = self.reqparse.parse_args() if "@" in args["username"]: user = user_service.get_by_email(args["username"]) else: user = user_service.get_by_username(args["username"]) # default to local authentication if user and user.check_password(args["password"]) and user.active: # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) metrics.send("login", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS}) return dict(token=create_token(user)) # try ldap login if current_app.config.get("LDAP_AUTH"): try: ldap_principal = ldap.LdapPrincipal(args) user = ldap_principal.authenticate() if user and user.active: # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) metrics.send( "login", "counter", 1, metric_tags={"status": SUCCESS_METRIC_STATUS}, ) return dict(token=create_token(user)) except Exception as e: current_app.logger.error("ldap error: {0}".format(e)) ldap_message = "ldap error: %s" % e metrics.send("login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}) return dict(message=ldap_message), 403 # if not valid user - no certificates for you metrics.send("login", "counter", 1, metric_tags={"status": FAILURE_METRIC_STATUS}) return dict(message="The supplied credentials are invalid"), 403
def run(self, password): create() user = user_service.get_by_username("lemur") admin_role = role_service.get_by_name('admin') if admin_role: sys.stdout.write("[-] Admin role already created, skipping...!\n") else: # we create an admin role admin_role = role_service.create('admin', description='This is the Lemur administrator role.') sys.stdout.write("[+] Created 'admin' role\n") operator_role = role_service.get_by_name('operator') if operator_role: sys.stdout.write("[-] Operator role already created, skipping...!\n") else: # we create an operator role operator_role = role_service.create('operator', description='This is the Lemur operator role.') sys.stdout.write("[+] Created 'operator' role\n") read_only_role = role_service.get_by_name('read-only') if read_only_role: sys.stdout.write("[-] Read only role already created, skipping...!\n") else: # we create an read only role read_only_role = role_service.create('read-only', description='This is the Lemur read only role.') sys.stdout.write("[+] Created 'read-only' role\n") if not user: if not password: sys.stdout.write("We need to set Lemur's password to continue!\n") password = prompt_pass("Password") password1 = prompt_pass("Confirm Password") if password != password1: sys.stderr.write("[!] Passwords do not match!\n") sys.exit(1) user_service.create("lemur", password, '*****@*****.**', True, None, [admin_role]) sys.stdout.write("[+] Created the user 'lemur' and granted it the 'admin' role!\n") else: sys.stdout.write("[-] Default user has already been created, skipping...!\n") intervals = current_app.config.get("LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS", []) sys.stdout.write( "[!] Creating {num} notifications for {intervals} days as specified by LEMUR_DEFAULT_EXPIRATION_NOTIFICATION_INTERVALS\n".format( num=len(intervals), intervals=",".join([str(x) for x in intervals]) ) ) recipients = current_app.config.get('LEMUR_SECURITY_TEAM_EMAIL') sys.stdout.write("[+] Creating expiration email notifications!\n") sys.stdout.write("[!] Using {0} as specified by LEMUR_SECURITY_TEAM_EMAIL for notifications\n".format(recipients)) notification_service.create_default_expiration_notifications("DEFAULT_SECURITY", recipients=recipients) _DEFAULT_ROTATION_INTERVAL = 'default' default_rotation_interval = policy_service.get_by_name(_DEFAULT_ROTATION_INTERVAL) if default_rotation_interval: sys.stdout.write("[-] Default rotation interval policy already created, skipping...!\n") else: days = current_app.config.get("LEMUR_DEFAULT_ROTATION_INTERVAL", 30) sys.stdout.write("[+] Creating default certificate rotation policy of {days} days before issuance.\n".format( days=days)) policy_service.create(days=days, name=_DEFAULT_ROTATION_INTERVAL) sys.stdout.write("[/] Done!\n")
def fetch_all_acme(): """ Attempt to get full certificates for each pending certificate listed with the acme-issuer. This is more efficient for acme-issued certificates because it will configure all of the DNS challenges prior to resolving any certificates. """ log_data = { "function": "{}.{}".format(__name__, sys._getframe().f_code.co_name) } pending_certs = pending_certificate_service.get_pending_certs('all') user = user_service.get_by_username('lemur') new = 0 failed = 0 wrong_issuer = 0 acme_certs = [] # We only care about certs using the acme-issuer plugin for cert in pending_certs: cert_authority = get_authority(cert.authority_id) if cert_authority.plugin_name == 'acme-issuer': acme_certs.append(cert) else: wrong_issuer += 1 authority = plugins.get("acme-issuer") resolved_certs = authority.get_ordered_certificates(acme_certs) for cert in resolved_certs: real_cert = cert.get("cert") # It's necessary to reload the pending cert due to detached instance: http://sqlalche.me/e/bhk3 pending_cert = pending_certificate_service.get( cert.get("pending_cert").id) if real_cert: # If a real certificate was returned from issuer, then create it in Lemur and delete # the pending certificate pending_certificate_service.create_certificate( pending_cert, real_cert, user) pending_certificate_service.delete_by_id(pending_cert.id) # add metrics to metrics extension new += 1 else: failed += 1 error_log = copy.deepcopy(log_data) error_log["message"] = "Pending certificate creation failure" error_log["pending_cert_id"] = pending_cert.id error_log["last_error"] = cert.get("last_error") error_log["cn"] = pending_cert.cn if pending_cert.number_attempts > 4: error_log["message"] = "Deleting pending certificate" send_pending_failure_notification( pending_cert, notify_owner=pending_cert.notify) pending_certificate_service.delete_by_id(pending_cert.id) current_app.logger.error(error_log) pending_certificate_service.increment_attempt(pending_cert) pending_certificate_service.update( cert.get("pending_cert").id, status=str(cert.get("last_error"))[0:128]) log_data["message"] = "Complete" log_data["new"] = new log_data["failed"] = failed log_data["wrong_issuer"] = wrong_issuer current_app.logger.debug(log_data) print( "[+] Certificates: New: {new} Failed: {failed} Not using ACME: {wrong_issuer}" .format(new=new, failed=failed, wrong_issuer=wrong_issuer))
def post(self): """ .. http:post:: /auth/login Login with username:password **Example request**: .. sourcecode:: http POST /auth/login HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "username": "******", "password": "******" } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "token": "12343243243" } :arg username: username :arg password: password :statuscode 401: invalid credentials :statuscode 200: no error """ self.reqparse.add_argument('username', type=str, required=True, location='json') self.reqparse.add_argument('password', type=str, required=True, location='json') args = self.reqparse.parse_args() if '@' in args['username']: user = user_service.get_by_email(args['username']) else: user = user_service.get_by_username(args['username']) # default to local authentication if user and user.check_password(args['password']) and user.active: # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS}) return dict(token=create_token(user)) # try ldap login if current_app.config.get("LDAP_AUTH"): try: ldap_principal = ldap.LdapPrincipal(args) user = ldap_principal.authenticate() if user and user.active: # Tell Flask-Principal the identity changed identity_changed.send(current_app._get_current_object(), identity=Identity(user.id)) metrics.send('login', 'counter', 1, metric_tags={'status': SUCCESS_METRIC_STATUS}) return dict(token=create_token(user)) except Exception as e: current_app.logger.error("ldap error: {0}".format(e)) ldap_message = 'ldap error: %s' % e metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS}) return dict(message=ldap_message), 403 # if not valid user - no certificates for you metrics.send('login', 'counter', 1, metric_tags={'status': FAILURE_METRIC_STATUS}) return dict(message='The supplied credentials are invalid'), 403