コード例 #1
0
ファイル: graphql.py プロジェクト: s2e-museum/king-phisher
	def _init_db(self):
		try:
			db_manager.init_database('sqlite://')
		except Exception as error:
			self.fail("failed to initialize the database (error: {0})".format(error.__class__.__name__))
		alice = db_models.User(id='alice', otp_secret='secret')
		calie = db_models.User(id='calie', otp_secret='secret')
		session = db_manager.Session()
		session.add(alice)
		session.add(calie)
		session.commit()
		session.close()
コード例 #2
0
	def rpc_login(self, session, username, password, otp=None):
		logger = logging.getLogger('KingPhisher.Server.Authentication')
		if not ipaddress.ip_address(self.client_address[0]).is_loopback:
			logger.warning("failed login request from {0} for user {1}, (invalid source address)".format(self.client_address[0], username))
			raise ValueError('invalid source address for login')
		fail_default = (False, ConnectionErrorReason.ERROR_INVALID_CREDENTIALS, None)
		fail_otp = (False, ConnectionErrorReason.ERROR_INVALID_OTP, None)

		if not (username and password):
			logger.warning("failed login request from {0} for user {1}, (missing username or password)".format(self.client_address[0], username))
			return fail_default
		if not self.server.forked_authenticator.authenticate(username, password):
			logger.warning("failed login request from {0} for user {1}, (authentication failed)".format(self.client_address[0], username))
			return fail_default

		user = db_manager.get_row_by_id(session, db_models.User, username)
		if not user:
			logger.info('creating new user object with id: ' + username)
			user = db_models.User(id=username)
			session.add(user)
			session.commit()
		elif user.otp_secret:
			if otp is None:
				logger.debug("failed login request from {0} for user {1}, (missing otp)".format(self.client_address[0], username))
				return fail_otp
			if not (isinstance(otp, str) and len(otp) == 6 and otp.isdigit()):
				logger.warning("failed login request from {0} for user {1}, (invalid otp)".format(self.client_address[0], username))
				return fail_otp
			totp = pyotp.TOTP(user.otp_secret)
			now = datetime.datetime.now()
			if not otp in (totp.at(now + datetime.timedelta(seconds=offset)) for offset in (0, -30, 30)):
				logger.warning("failed login request from {0} for user {1}, (invalid otp)".format(self.client_address[0], username))
				return fail_otp
		logger.info("successful login request from {0} for user {1}".format(self.client_address[0], username))
		return True, ConnectionErrorReason.SUCCESS, self.server.session_manager.put(username)
コード例 #3
0
 def setUp(self):
     username = '******'
     self._session = db_manager.Session()
     self.user = self._session.query(
         db_models.User).filter_by(name=username).first()
     if self.user is None:
         self.user = db_models.User(name=username)
         self._session.add(self.user)
         self._session.commit()
コード例 #4
0
	def rpc_test_login(self, username, password, otp=None):
		session = db_manager.Session()
		user = session.query(db_models.User).filter_by(name=username).first()
		if not user:
			user = db_models.User(name=username)
		user.last_login = db_models.current_timestamp()
		session.add(user)
		session.commit()
		session_id = self.server.session_manager.put(user)
		session.close()
		return True, constants.ConnectionErrorReason.SUCCESS, session_id
コード例 #5
0
ファイル: database.py プロジェクト: yonghengshi/king-phisher
	def test_get_row_by_id(self):
		self._init_db()
		session = db_manager.Session()
		user = db_models.User(id='alice')
		session.add(user)
		campaign_name = random_string(10)
		campaign = db_models.Campaign(name=campaign_name, user_id=user.id)
		session.add(campaign)
		session.commit()
		self.assertIsNotNone(campaign.id)
		campaign_id = campaign.id
		del campaign

		row = db_manager.get_row_by_id(session, db_models.Campaign, campaign_id)
		self.assertEqual(row.id, campaign_id)
		self.assertEqual(row.name, campaign_name)
コード例 #6
0
ファイル: server_rpc.py プロジェクト: washal/king-phisher
    def rpc_client_initialize(self):
        """
		Initialize any client information necessary.

		:return: This method always returns True.
		:rtype: bool
		"""
        username = self.basic_auth_user
        if not username:
            return True
        session = db_manager.Session()
        if not db_manager.get_row_by_id(session, db_models.User, username):
            user = db_models.User(id=username)
            session.add(user)
            session.commit()
        session.close()
        return True
コード例 #7
0
def rpc_login(handler, session, username, password, otp=None):
	logger = logging.getLogger('KingPhisher.Server.Authentication')
	if not ipaddress.ip_address(handler.client_address[0]).is_loopback:
		logger.warning("failed login request from {0} for user {1}, (invalid source address)".format(handler.client_address[0], username))
		raise ValueError('invalid source address for login')
	fail_default = (False, ConnectionErrorReason.ERROR_INVALID_CREDENTIALS, None)
	fail_otp = (False, ConnectionErrorReason.ERROR_INVALID_OTP, None)

	if not (username and password):
		logger.warning("failed login request from {0} for user {1}, (missing username or password)".format(handler.client_address[0], username))
		return fail_default
	if not handler.server.forked_authenticator.authenticate(username, password):
		logger.warning("failed login request from {0} for user {1}, (authentication failed)".format(handler.client_address[0], username))
		return fail_default

	user = session.query(db_models.User).filter_by(name=username).first()
	if not user:
		logger.info('creating new user object with name: ' + username)
		user = db_models.User(name=username)
	elif user.has_expired:
		logger.warning("failed login request from {0} for user {1}, (user has expired)".format(handler.client_address[0], username))
		return fail_default
	elif user.otp_secret:
		if otp is None:
			logger.debug("failed login request from {0} for user {1}, (missing otp)".format(handler.client_address[0], username))
			return fail_otp
		if not (isinstance(otp, str) and len(otp) == 6 and otp.isdigit()):
			logger.warning("failed login request from {0} for user {1}, (invalid otp)".format(handler.client_address[0], username))
			return fail_otp
		totp = pyotp.TOTP(user.otp_secret)
		now = datetime.datetime.now()
		if otp not in (totp.at(now + datetime.timedelta(seconds=offset)) for offset in (0, -30, 30)):
			logger.warning("failed login request from {0} for user {1}, (invalid otp)".format(handler.client_address[0], username))
			return fail_otp
	user.last_login = db_models.current_timestamp()
	session.add(user)
	session.commit()
	session_id = handler.server.session_manager.put(user)
	logger.info("successful login request from {0} for user {1}".format(handler.client_address[0], username))
	signals.send_safe('rpc-user-logged-in', logger, handler, session=session_id, name=username)
	return True, ConnectionErrorReason.SUCCESS, session_id
コード例 #8
0
def main():
    parser = argparse.ArgumentParser(
        description='King Phisher TOTP Enrollment Utility',
        conflict_handler='resolve')
    utilities.argp_add_args(parser)
    config_group = parser.add_mutually_exclusive_group(required=True)
    config_group.add_argument('-c',
                              '--config',
                              dest='server_config',
                              type=argparse.FileType('r'),
                              help='the server configuration file')
    config_group.add_argument('-u',
                              '--url',
                              dest='database_url',
                              help='the database connection url')
    parser.add_argument('--force',
                        dest='force',
                        action='store_true',
                        default=False,
                        help='create the user if necessary')
    parser.add_argument('--otp',
                        dest='otp_secret',
                        help='a specific otp secret')
    if has_qrcode:
        parser.add_argument('--qrcode',
                            dest='qrcode_filename',
                            help='generate a qrcode image file')
    parser.add_argument('user', help='the user to mange')
    parser.add_argument('action',
                        choices=('remove', 'set', 'show'),
                        help='the action to preform')
    parser.epilog = PARSER_EPILOG
    arguments = parser.parse_args()

    if arguments.database_url:
        database_connection_url = arguments.database_url
    elif arguments.server_config:
        server_config = yaml.load(arguments.server_config)
        database_connection_url = server_config['server']['database']
    else:
        raise RuntimeError('no database connection was specified')

    manager.init_database(database_connection_url)
    session = manager.Session()
    user = session.query(models.User).filter_by(id=arguments.user).first()
    if not user:
        if not arguments.force:
            color.print_error("invalid user id: {0}".format(arguments.user))
            return
        user = models.User(id=arguments.user)
        session.add(user)
        color.print_status('the specified user was created')

    for case in utilities.switch(arguments.action):
        if case('remove'):
            user.otp_secret = None
            break
        if case('set'):
            if user.otp_secret:
                color.print_error(
                    "the specified user already has an otp secret set")
                return
            if arguments.otp_secret:
                new_otp = arguments.otp_secret
            else:
                new_otp = pyotp.random_base32()
            if len(new_otp) != 16:
                color.print_error("invalid otp secret length, must be 16")
                return
            user.otp_secret = new_otp
            break

    if user.otp_secret:
        color.print_status("user: {0} otp: {1}".format(user.id,
                                                       user.otp_secret))
        totp = pyotp.TOTP(user.otp_secret)
        uri = totp.provisioning_uri(user.id +
                                    '@king-phisher') + '&issuer=King%20Phisher'
        color.print_status("provisioning uri: {0}".format(uri))
        if has_qrcode and arguments.qrcode_filename:
            img = qrcode.make(uri)
            img.save(arguments.qrcode_filename)
            color.print_status("wrote qrcode image to: " +
                               arguments.qrcode_filename)
    else:
        color.print_status("user: {0} otp: N/A".format(user.id))
    session.commit()
コード例 #9
0
 def test_models_convert_to_dictionaries(self):
     model = db_models.User(name='alice')
     dictionary = model.to_dict()
     self.assertIsInstance(dictionary, dict)
     self.assertIn('name', dictionary)
コード例 #10
0
ファイル: models.py プロジェクト: zhangway100/king-phisher
 def test_users_dont_default_to_admin(self):
     user = db_models.User(name='alice')
     self.assertFalse(user.is_admin)