Beispiel #1
0
    def _on_server(self, args):
        
        repo_dir = join(self.config_dir, 'repo')
        server_conf = ConfigObj(join(repo_dir, 'server.conf'))

        cm = CryptoManager(priv_key_location=abspath(join(repo_dir, server_conf['crypto']['priv_key_location'])))
        cm.load_keys()
        
        engine_params = dict(server_conf['odb'].items())
        engine_params['extra'] = {}
        engine_params['pool_size'] = 1
        
        query = ping_queries[engine_params['engine']]
        
        session = create_pool(cm, engine_params)
        session.execute(query)
        session.close()
        
        if self.show_output:
            self.logger.info('SQL ODB connection OK')
        
        kvdb_config = Bunch(dict(server_conf['kvdb'].items()))
        kvdb = KVDB(None, kvdb_config, cm.decrypt)
        kvdb.init()
        
        kvdb.conn.info()
        kvdb.close()
        
        if self.show_output:
            self.logger.info('Redis connection OK')
Beispiel #2
0
def set_initial_opaque_attrs(username, initial, opaque_attrs):

    # By default, opaque attributes are not set for user
    if opaque_attrs:
        opaque_attrs = loads(opaque_attrs)

        for attr in profile_attrs_opaque:
            initial[attr] = opaque_attrs.get(attr) or ''

    # Generate or use the existing TOTP key
    totp_key = initial.get('totp_key')
    if not totp_key:
        totp_key = pyotp.random_base32()
        initial['totp_key_label'] = 'Zato web-admin'
    else:
        cm = CryptoManager(secret_key=zato_settings.zato_secret_key)

        # TOTP key is always decrypted so we need to decrypt it here
        totp_key = cm.decrypt(totp_key)

        # .. same goes for its label
        initial['totp_key_label'] = cm.decrypt(initial['totp_key_label'])

    # Build the actual TOTP object for later use
    totp = pyotp.totp.TOTP(totp_key)

    # Update template data with TOTP information
    initial['totp_key'] = totp.secret
    initial['totp_key_provision_uri'] = totp.provisioning_uri(
        username, issuer_name=initial['totp_key_label'])
Beispiel #3
0
    def _on_server(self, args):
        
        repo_dir = join(self.config_dir, 'repo')
        server_conf = ConfigObj(join(repo_dir, 'server.conf'))

        cm = CryptoManager(priv_key_location=abspath(join(repo_dir, server_conf['crypto']['priv_key_location'])))
        cm.load_keys()
        
        engine_params = dict(server_conf['odb'].items())
        engine_params['extra'] = {}
        engine_params['pool_size'] = 1
        
        query = ping_queries[engine_params['engine']]
        
        session = create_pool(cm, engine_params)
        session.execute(query)
        session.close()
        
        if self.show_output:
            self.logger.info('SQL ODB connection OK')
        
        kvdb_config = Bunch(dict(server_conf['kvdb'].items()))
        kvdb = KVDB(None, kvdb_config, cm.decrypt)
        kvdb.init()
        
        kvdb.conn.info()
        kvdb.close()
        
        if self.show_output:
            self.logger.info('Redis connection OK')
Beispiel #4
0
 def test_enrypt(self):
     """ Encrypt a message using the public key.
     """
     _plain_text = uuid4().hex
     
     with NamedTemporaryFile(prefix='zato-test-') as tf_priv:
         with NamedTemporaryFile(prefix='zato-test-') as tf_pub:
             
             tf_priv.write(priv_key)
             tf_priv.flush()
             
             tf_pub.write(pub_key)
             tf_pub.flush()
             
             cm_priv = CryptoManager()
             cm_priv.priv_key_location = tf_priv.name
             cm_priv.load_keys()
             
             cm_pub = CryptoManager()
             cm_pub.pub_key_location = tf_pub.name
             cm_pub.load_keys()
             
             encrypted = cm_pub.encrypt(_plain_text)
             decrypted = cm_priv.decrypt(encrypted)
             
             eq_(_plain_text, decrypted)
Beispiel #5
0
    def execute(self, args):

        repo_dir = os.path.join(os.path.abspath(os.path.join(self.original_dir, args.path)), 'config', 'repo')
        config = get_config(repo_dir, 'server.conf')
        priv_key_location = os.path.abspath(os.path.join(repo_dir, config.crypto.priv_key_location))
        
        cm = CryptoManager(priv_key_location=priv_key_location)
        cm.load_keys()
        
        engine_args = Bunch()
        engine_args.odb_type = config.odb.engine
        engine_args.odb_user = config.odb.username
        engine_args.odb_password = cm.decrypt(config.odb.password)
        engine_args.odb_host = config.odb.host
        engine_args.odb_db_name = config.odb.db_name
        
        engine = self._get_engine(engine_args)
        session = self._get_session(engine)
        
        auth = None
        headers = {}
        
        with closing(session) as session:
            cluster = session.query(Server).\
                filter(Server.token == config.main.token).\
                one().cluster
            
            channel = session.query(HTTPSOAP).\
                filter(HTTPSOAP.cluster_id == cluster.id).\
                filter(HTTPSOAP.url_path == args.url_path).\
                one()
            
            if channel.security_id:
                security = session.query(HTTPBasicAuth).\
                    filter(HTTPBasicAuth.id == channel.security_id).\
                    first()
                
                if security:
                    auth = (security.username, security.password)
                    
        if args.headers:
            for pair in args.headers.strip().split(';'):
                k, v = pair.strip().split('=', 1)
                headers[k] = v
                    
        client = AnyServiceInvoker('http://{}'.format(config.main.gunicorn_bind), args.url_path, auth,
            max_response_repr=int(args.max_response_repr), max_cid_repr=int(args.max_cid_repr))
        
        func = client.invoke_async if args.async else client.invoke
        response = func(args.name, args.payload, headers, args.channel, args.data_format, args.transport)
        
        if response.ok:
            self.logger.info(response.data or '(None)')
        else:
            self.logger.error(response.details)
            
        if args.verbose:
            self.logger.debug('inner.text:[{}]'.format(response.inner.text))
            self.logger.debug('response:[{}]'.format(response))
Beispiel #6
0
def get_crypto_manager_from_server_config(config, repo_dir):

    priv_key_location = os.path.abspath(os.path.join(repo_dir, config.crypto.priv_key_location))

    cm = CryptoManager(priv_key_location=priv_key_location)
    cm.load_keys()

    return cm
Beispiel #7
0
def get_crypto_manager_from_server_config(config, repo_dir):

    priv_key_location = os.path.abspath(os.path.join(repo_dir, config.crypto.priv_key_location))

    cm = CryptoManager(priv_key_location=priv_key_location)
    cm.load_keys()

    return cm
Beispiel #8
0
 def xtest_decrypt_priv_key_in_string(self):
     """ Decrypt a message using a private key from string.
     """
     cm = CryptoManager()
     cm.priv_key = priv_key
     cm.load_keys()
     
     eq_(plain_text, cm.decrypt(secret))
Beispiel #9
0
    def xtest_reset(self):
        """ Resets all keys to None.
        """
        cm = CryptoManager()
        cm.reset()

        eq_(cm.priv_key_location, None)
        eq_(cm.pub_key_location, None)
        eq_(cm.priv_key, None)
        eq_(cm.pub_key, None)
Beispiel #10
0
 def xtest_reset(self):
     """ Resets all keys to None.
     """
     cm = CryptoManager()
     cm.reset()
     
     eq_(cm.priv_key_location, None)
     eq_(cm.pub_key_location, None)
     eq_(cm.priv_key, None)
     eq_(cm.pub_key, None)
Beispiel #11
0
    def _update_crypto(
            self, args, copy_crypto_func, update_secrets=False, load_secrets_func=None,
            store_secrets_func=None, conf_file_name=None, priv_key_name=None, pub_key_name=None, secret_names=[]):

        repo_dir = os.path.join(os.path.abspath(os.path.join(self.original_dir, args.path)), 'config', 'repo')
        secrets = {}

        if update_secrets:
            priv_key_location = os.path.abspath(os.path.join(repo_dir, priv_key_name))
            pub_key_location = os.path.abspath(os.path.join(repo_dir, pub_key_name))
            conf_location = os.path.join(repo_dir, conf_file_name)

            cm = CryptoManager(priv_key_location=priv_key_location)
            cm.load_keys()

            secrets, conf = load_secrets_func(secrets, secret_names, cm, conf_location, conf_file_name)

        copy_crypto_func(repo_dir, args)

        if update_secrets:
            cm.reset()
            cm.pub_key_location = pub_key_location
            cm.load_keys()

            store_secrets_func(secrets, secret_names, cm, conf_location, conf)
Beispiel #12
0
    def _on_server(self, args):

        repo_dir = join(self.config_dir, 'repo')
        server_conf = ConfigObj(join(repo_dir, 'server.conf'))

        cm = CryptoManager(priv_key_location=abspath(join(repo_dir, server_conf['crypto']['priv_key_location'])))
        cm.load_keys()

        self.on_server_check_sql_odb(cm, server_conf, repo_dir)
        self.on_server_check_kvdb(cm, server_conf)
        self.on_server_check_stale_unix_socket()
Beispiel #13
0
def decrypt(data, priv_key, b64=True):
    """ Decrypts data using the given private key.
    data - data to be encrypted
    priv_key - private key to use (as a PEM string)
    b64 - should the data be BASE64-decoded before being decrypted, defaults to True
    """

    cm = CryptoManager(priv_key=priv_key)
    cm.load_keys()

    return cm.decrypt(data, b64)
Beispiel #14
0
def decrypt(data, priv_key, b64=True):
    """ Decrypts data using the given private key.
    data - data to be encrypted
    priv_key - private key to use (as a PEM string)
    b64 - should the data be BASE64-decoded before being decrypted, defaults to True
    """

    cm = CryptoManager(priv_key=priv_key)
    cm.load_keys()

    return cm.decrypt(data, b64)
Beispiel #15
0
def encrypt(data, priv_key, b64=True):
    """ Encrypt data using a public key derived from the private key.
    data - data to be encrypted
    priv_key - private key to use (as a PEM string)
    b64 - should the encrypted data be BASE64-encoded before being returned, defaults to True
    """

    cm = CryptoManager(priv_key=priv_key)
    cm.load_keys()

    return cm.encrypt(data, b64)
Beispiel #16
0
def encrypt(data, priv_key, b64=True):
    """ Encrypt data using a public key derived from the private key.
    data - data to be encrypted
    priv_key - private key to use (as a PEM string)
    b64 - should the encrypted data be BASE64-encoded before being returned, defaults to True
    """

    cm = CryptoManager(priv_key=priv_key)
    cm.load_keys()

    return cm.encrypt(data, b64)
Beispiel #17
0
 def xtest_decrypt_priv_key_in_file(self):
     """ Decrypt a message using a private key from file.
     """
     with NamedTemporaryFile(prefix='zato-test-') as tf:
         tf.write(priv_key)
         tf.flush()
         
         cm = CryptoManager()
         cm.priv_key_location = tf.name
         cm.load_keys()
         
         eq_(plain_text, cm.decrypt(secret))
    def get_crypto_manager_conf(self, conf_file=None, priv_key_location=None, repo_dir=None):
        repo_dir = repo_dir or join(self.config_dir, 'repo')
        conf = None

        if not priv_key_location:
            conf = ConfigObj(join(repo_dir, conf_file))
            priv_key_location = priv_key_location or abspath(join(repo_dir, conf['crypto']['priv_key_location']))

        cm = CryptoManager(priv_key_location=priv_key_location)
        cm.load_keys()

        return cm, conf
Beispiel #19
0
def encrypt(data, pub_key, padding=RSA.pkcs1_padding, b64=True):
    """ Encrypt data using the given public key.
    data - data to be encrypted
    pub_key - public key to use (as a PEM string)
    padding - padding to use, defaults to PKCS#1
    b64 - should the encrypted data be BASE64-encoded before being returned, defaults to True
    """
    logger.debug('Using pub_key:[{}]'.format(pub_key))
    
    cm = CryptoManager(pub_key=pub_key)
    cm.load_keys()
    
    return cm.encrypt(data, padding, b64)
Beispiel #20
0
def decrypt(data, priv_key, padding=RSA.pkcs1_padding, b64=True):
    """ Decrypts data using the given private key.
    data - data to be encrypted
    priv_key - private key to use (as a PEM string)
    padding - padding to use, defaults to PKCS#1
    b64 - should the data be BASE64-decoded before being decrypted, defaults to True
    """
    logger.debug('Using priv_key:[{}]'.format(priv_key))

    cm = CryptoManager(priv_key=priv_key)
    cm.load_keys()

    return cm.decrypt(data, padding, b64)
Beispiel #21
0
def decrypt(data, priv_key, padding=RSA.pkcs1_padding, b64=True):
    """ Decrypts data using the given private key.
    data - data to be encrypted
    priv_key - private key to use (as a PEM string)
    padding - padding to use, defaults to PKCS#1
    b64 - should the data be BASE64-decoded before being decrypted, defaults to True
    """
    logger.debug('Using priv_key:[{}]'.format(priv_key))
    
    cm = CryptoManager(priv_key=priv_key)
    cm.load_keys()
    
    return cm.decrypt(data, padding, b64)
Beispiel #22
0
def encrypt(data, pub_key, padding=RSA.pkcs1_padding, b64=True):
    """ Encrypt data using the given public key.
    data - data to be encrypted
    pub_key - public key to use (as a PEM string)
    padding - padding to use, defaults to PKCS#1
    b64 - should the encrypted data be BASE64-encoded before being returned, defaults to True
    """
    logger.debug('Using pub_key:[{}]'.format(pub_key))

    cm = CryptoManager(pub_key=pub_key)
    cm.load_keys()

    return cm.encrypt(data, padding, b64)
Beispiel #23
0
 def _update_crypto(
         self, args, copy_crypto_func, update_secrets=False, load_secrets_func=None,
         store_secrets_func=None, conf_file_name=None, priv_key_name=None, pub_key_name=None, secret_names=[]):
     
     repo_dir = os.path.join(os.path.abspath(os.path.join(self.original_dir, args.path)), 'config', 'repo')
     secrets = {}
     
     if update_secrets:
         priv_key_location = os.path.abspath(os.path.join(repo_dir, priv_key_name))
         pub_key_location = os.path.abspath(os.path.join(repo_dir, pub_key_name))
         conf_location = os.path.join(repo_dir, conf_file_name)
         
         cm = CryptoManager(priv_key_location=priv_key_location)
         cm.load_keys()
         
         secrets, conf = load_secrets_func(secrets, secret_names, cm, conf_location, conf_file_name)
         
     copy_crypto_func(repo_dir, args)
     
     if update_secrets:
         cm.reset()
         cm.pub_key_location = pub_key_location
         cm.load_keys()
         
         store_secrets_func(secrets, secret_names, cm, conf_location, conf)
Beispiel #24
0
    def _on_server(self, args):

        repo_dir = join(self.config_dir, 'repo')
        server_conf = ConfigObj(join(repo_dir, 'server.conf'))

        cm = CryptoManager(priv_key_location=abspath(join(repo_dir, server_conf['crypto']['priv_key_location'])))
        cm.load_keys()

        self.on_server_check_sql_odb(cm, server_conf, repo_dir)
        self.on_server_check_kvdb(cm, server_conf)

        # enmasse actually needs a sockets because it means a server is running
        # so we can't quit if one is available.
        if getattr(args, 'check_stale_server_sockets', True):
            self.on_server_check_stale_unix_socket()
Beispiel #25
0
    def _get_sso_config(self, args, repo_location, secrets_conf):
        # type: (Namespace, unicode, Bunch) -> UserAPI
        sso_conf = get_config(repo_location,
                              'sso.conf',
                              needs_user_config=False)
        normalize_password_reject_list(sso_conf)

        crypto_manager = CryptoManager.from_secret_key(
            secrets_conf.secret_keys.key1)
        crypto_manager.add_hash_scheme('sso.super-user',
                                       sso_conf.hash_secret.rounds,
                                       sso_conf.hash_secret.salt_size)

        server_conf = get_config(repo_location,
                                 'server.conf',
                                 needs_user_config=False,
                                 crypto_manager=crypto_manager,
                                 secrets_conf=secrets_conf)

        def _get_session():
            return self.get_odb_session_from_server_config(server_conf, None)

        def _hash_secret(_secret):
            return crypto_manager.hash_secret(_secret, 'sso.super-user')

        return UserAPI(None, sso_conf, _get_session, crypto_manager.encrypt,
                       crypto_manager.decrypt, _hash_secret, None, new_user_id)
Beispiel #26
0
    def get_crypto_manager_conf(self,
                                conf_file=None,
                                priv_key_location=None,
                                repo_dir=None):
        repo_dir = repo_dir or join(self.config_dir, 'repo')
        conf = None

        if not priv_key_location:
            conf = ConfigObj(join(repo_dir, conf_file))
            priv_key_location = priv_key_location or abspath(
                join(repo_dir, conf['crypto']['priv_key_location']))

        cm = CryptoManager(priv_key_location=priv_key_location)
        cm.load_keys()

        return cm, conf
Beispiel #27
0
    def _on_sso_command(self, args, user, user_api):
        # type: (Namespace, SSOUser, UserAPI)

        if user_api.get_user_by_username('', args.username):
            self.logger.warn('User already exists `%s`', args.username)
            return self.SYS_ERROR.USER_EXISTS

        try:
            user_api.validate_password(args.password)
        except ValidationError as e:
            self.logger.warn('Password validation error, reason code:`%s`',
                             ', '.join(e.sub_status))
            return self.SYS_ERROR.VALIDATION_ERROR

        data = Bunch()
        data.username = args.username
        data.email = args.email or b''
        data.display_name = args.display_name or b''
        data.first_name = args.first_name or b''
        data.middle_name = args.middle_name or b''
        data.last_name = args.last_name or b''
        data.password = args.password
        data.sign_up_confirm_token = 'cli.{}'.format(
            CryptoManager.generate_secret())
        data.is_rate_limit_active = False
        data.rate_limit_def = None
        data.rate_limit_type = None
        data.rate_limit_check_parent_def = False

        func = getattr(user_api, self.create_func)
        func(_cid, data, require_super_user=False, auto_approve=True)

        self.logger.info('Created %s `%s`', self.user_type, data.username)
Beispiel #28
0
 def _on_sso_command(self, args, user, user_api):
     new_password = CryptoManager.generate_password()
     user_api.set_password('cli', user.user_id, new_password,
                           args.must_change, args.expiry, _current_app,
                           _current_host)
     self.logger.info('Password for user `%s` reset to `%s`', args.username,
                      new_password)
Beispiel #29
0
    def _on_server(self, args):

        repo_dir = join(self.config_dir, 'repo')
        server_conf = ConfigObj(join(repo_dir, 'server.conf'))

        cm = CryptoManager(priv_key_location=abspath(
            join(repo_dir, server_conf['crypto']['priv_key_location'])))
        cm.load_keys()

        self.on_server_check_sql_odb(cm, server_conf, repo_dir)
        self.on_server_check_kvdb(cm, server_conf)

        # enmasse actually needs a sockets because it means a server is running
        # so we can't quit if one is available.
        if getattr(args, 'check_stale_server_sockets', True):
            self.on_server_check_stale_unix_socket()
    def _on_web_admin(self, args):
        """Load ODB using component config and update security definition."""
        config_file = join(self.config_dir, 'repo', 'web-admin.conf')

        with open(config_file) as fp:
            c = bunchify(load(fp))

        private_key = join(self.config_dir, 'repo', 'web-admin-priv-key.pem')
        cm = CryptoManager(priv_key_location=private_key)
        cm.load_keys()
        db_password = cm.decrypt(c.DATABASE_PASSWORD)

        engine_url = "%s://%s:%s@%s:%s/%s" % (
            c.db_type,
            c.DATABASE_USER,
            db_password,
            c.DATABASE_HOST,
            c.DATABASE_PORT,
            c.DATABASE_NAME)

        engine = sqlalchemy.create_engine(engine_url)
        session = self._get_session(engine)

        if engine.dialect.has_table(engine.connect(), 'sec_basic_auth'):
            try:
                secdef = session.query(HTTPBasicAuth).filter(
                    HTTPBasicAuth.name == args.secdef).one()
            except sqlalchemy.orm.exc.NoResultFound:
                self.logger.error(
                    "Security definition '%s' not found.", args.secdef)
                return 1

            self.logger.info("Security definition: %s" % secdef.name)
            self.logger.info("Username: %s" % secdef.username)
            self.logger.info("Old password: %s" % secdef.password)
            self.logger.info("Setting new password.")
            secdef.password = args.password
            session.commit()
            self.logger.info('OK')
        else:
            msg = "Zato ODB does not seem to have been set up yet."
            self.logger.error(msg)
            return self.SYS_ERROR.NO_ODB_FOUND
Beispiel #31
0
def set_user_profile_totp_key(user_profile,
                              zato_secret_key,
                              totp_key,
                              totp_key_label=None,
                              opaque_attrs=None):

    if not opaque_attrs:
        opaque_attrs = user_profile.opaque1
        opaque_attrs = loads(opaque_attrs) if opaque_attrs else {}

    cm = CryptoManager(secret_key=zato_secret_key)

    # TOTP key is always encrypted
    totp_key = cm.encrypt(totp_key.encode('utf8'))
    opaque_attrs['totp_key'] = totp_key

    # .. and so is its label
    if totp_key_label:
        totp_key_label = cm.encrypt(totp_key_label.encode('utf8'))
        opaque_attrs['totp_key_label'] = totp_key_label

    return opaque_attrs
    def _on_web_admin(self, args):
        """Load ODB using component config and update security definition."""
        config_file = join(self.config_dir, 'repo', 'web-admin.conf')

        with open(config_file) as fp:
            c = bunchify(load(fp))

        private_key = join(self.config_dir, 'repo', 'web-admin-priv-key.pem')
        cm = CryptoManager(priv_key_location=private_key)
        cm.load_keys()
        db_password = cm.decrypt(c.DATABASE_PASSWORD)

        engine_url = "%s://%s:%s@%s:%s/%s" % (c.db_type, c.DATABASE_USER,
                                              db_password, c.DATABASE_HOST,
                                              c.DATABASE_PORT, c.DATABASE_NAME)

        engine = sqlalchemy.create_engine(engine_url)
        session = self._get_session(engine)

        if engine.dialect.has_table(engine.connect(), 'sec_basic_auth'):
            try:
                secdef = session.query(HTTPBasicAuth).filter(
                    HTTPBasicAuth.name == args.secdef).one()
            except sqlalchemy.orm.exc.NoResultFound:
                self.logger.error("Security definition '%s' not found.",
                                  args.secdef)
                return 1

            self.logger.info("Security definition: %s" % secdef.name)
            self.logger.info("Username: %s" % secdef.username)
            self.logger.info("Old password: %s" % secdef.password)
            self.logger.info("Setting new password.")
            secdef.password = args.password
            session.commit()
            self.logger.info('OK')
        else:
            msg = "Zato ODB does not seem to have been set up yet."
            self.logger.error(msg)
            return self.SYS_ERROR.NO_ODB_FOUND
Beispiel #33
0
    def xtest_decrypt_priv_key_in_string(self):
        """ Decrypt a message using a private key from string.
        """
        cm = CryptoManager()
        cm.priv_key = priv_key
        cm.load_keys()

        eq_(plain_text, cm.decrypt(secret))
Beispiel #34
0
    def execute(self, args):
        goal = round(float(args.goal), 2)

        if args.json or args.rounds_only:
            header_func, progress_func, footer_func = None, None, None
        else:
            header_func, progress_func, footer_func = self.header_func, self.progress_func, self.footer_func

        info = CryptoManager.get_hash_rounds(goal, header_func, progress_func, footer_func)

        if args.json:
            self.logger.info(anyjson.dumps(info))
        elif args.rounds_only:
            self.logger.info(info['rounds'])
Beispiel #35
0
    def _login_super_user(self):
        response = self.post(
            '/zato/sso/user/login', {
                'username':
                Config.super_user_name,
                'password':
                Config.super_user_password,
                'totp_code':
                CryptoManager.get_current_totp_code(
                    Config.super_user_totp_key),
            })
        self.ctx.super_user_ust = response.ust

        response = self.get('/zato/sso/user', {
            'ust': self.ctx.super_user_ust,
        })
        self.ctx.super_user_id = response.user_id
Beispiel #36
0
    def xtest_decrypt_priv_key_in_file(self):
        """ Decrypt a message using a private key from file.
        """
        with NamedTemporaryFile(prefix='zato-test-') as tf:
            tf.write(priv_key)
            tf.flush()

            cm = CryptoManager()
            cm.priv_key_location = tf.name
            cm.load_keys()

            eq_(plain_text, cm.decrypt(secret))
Beispiel #37
0
    def __init__(self, config, repo_location):
        self.odb = config.odb
        self.config = config
        self.repo_location = repo_location
        self.sql_pool_store = PoolStore()

        # Set up the crypto manager that will be used by both ODB and, possibly, KVDB
        self.config.crypto_manager = get_crypto_manager(
            self.repo_location,
            None,
            config.main,
            crypto_manager=CryptoManager())

        # ODB connection
        self.odb = ODBManager()

        if self.config.main.odb.engine != 'sqlite':
            self.config.main.odb.password = self.config.crypto_manager.decrypt(
                config.main.odb.password)
            self.config.main.odb.host = config.main.odb.host
            self.config.main.odb.pool_size = config.main.odb.pool_size
            self.config.main.odb.username = config.main.odb.username

        self.sql_pool_store[ZATO_ODB_POOL_NAME] = self.config.main.odb

        main = self.config.main

        if main.crypto.use_tls:
            priv_key, cert = main.crypto.priv_key_location, main.crypto.cert_location
        else:
            priv_key, cert = None, None

        # API server
        self.api_server = WSGIServer((main.bind.host, int(main.bind.port)),
                                     self,
                                     keyfile=priv_key,
                                     certfile=cert)

        self.odb.pool = self.sql_pool_store[ZATO_ODB_POOL_NAME].pool
        self.odb.init_session(ZATO_ODB_POOL_NAME, self.config.main.odb,
                              self.odb.pool, False)
        self.config.odb = self.odb

        # Scheduler
        self.scheduler = Scheduler(self.config)
Beispiel #38
0
def get_totp_info_from_args(args, default_key_label=TOTP.default_label):
    """ Returns a key and its label extracted from command line arguments
    or auto-generates a new pair if they are missing in args.
    """
    # type: (Namespace, unicode) -> (unicode, unicode)

    # If there was a key given on input, we need to validate it,
    # this report an erorr if the key cannot be used.
    if args.key:
        totp = pyotp.TOTP(args.key)
        totp.now()

        # If we are here, it means that the key was valid
        key = args.key
    else:
        key = CryptoManager.generate_totp_key()

    return key, args.key_label if args.key_label else default_key_label
Beispiel #39
0
    def test_user_login_totp_valid(self):

        self.patch(
            '/zato/sso/user', {
                'ust': self.ctx.super_user_ust,
                'is_totp_enabled': True,
                'totp_key': self.ctx.config.super_user_totp_key,
            })

        response = self.post(
            '/zato/sso/user/login', {
                'username':
                self.ctx.config.super_user_name,
                'password':
                self.ctx.config.super_user_password,
                'totp_code':
                CryptoManager.get_current_totp_code(
                    self.ctx.config.super_user_totp_key),
            })

        self.assertIsNotNone(response.ust)
Beispiel #40
0
 def execute(self, args):
     self.logger.info(CryptoManager.generate_key())
Beispiel #41
0
    def execute(self, args):
        cm = CryptoManager(priv_key_location=os.path.abspath(args.path))
        cm.load_keys()

        self.logger.info('Secret is [{}]'.format(cm.decrypt(args.secret)))
Beispiel #42
0
    def execute(self, args):
        cm = CryptoManager(pub_key_location=os.path.abspath(args.path))
        cm.load_keys()

        self.logger.info('Encrypted value is [{}]'.format(
            cm.encrypt(args.secret)))
Beispiel #43
0
    def execute(self, args):
        """ Quickly creates Zato components
        1) CA and crypto material
        2) ODB
        3) ODB initial data
        4) servers
        5) load-balancer
        6) Web admin
        7) Scheduler
        8) Scripts
        """

        if args.odb_type == 'sqlite':
            args.sqlite_path = os.path.abspath(
                os.path.join(args.path, 'zato.db'))
        '''
        cluster_id_args = Bunch()
        cluster_id_args.odb_db_name = args.odb_db_name
        cluster_id_args.odb_host = args.odb_host
        cluster_id_args.odb_password = args.odb_password
        cluster_id_args.odb_port = args.odb_port
        cluster_id_args.odb_type = args.odb_type
        cluster_id_args.odb_user = args.odb_user
        cluster_id_args.postgresql_schema = args.postgresql_schema
        cluster_id_args.sqlite_path = args.sqlite_path
        '''

        next_step = count(1)
        next_port = count(http_plain_server_port)
        cluster_name = getattr(args, 'cluster_name',
                               None) or 'quickstart-{}'.format(
                                   random.getrandbits(20)).zfill(7)
        servers = int(getattr(args, 'servers', 0) or DEFAULT_NO_SERVERS)

        server_names = OrderedDict()
        for idx in range(1, servers + 1):
            server_names['{}'.format(idx)] = 'server{}'.format(idx)

        total_steps = 7 + servers
        admin_invoke_password = uuid4().hex
        broker_host = 'localhost'
        broker_port = 6379
        lb_host = 'localhost'
        lb_port = 11223
        lb_agent_port = 20151

        args_path = os.path.abspath(args.path)

        # This could've been set to True by user in the command-line so we'd want
        # to unset it so that individual commands quickstart invokes don't attempt
        # to store their own configs.
        args.store_config = False

        # ################################################################################################################################

        #
        # 1) CA
        #
        ca_path = os.path.join(args_path, 'ca')
        os.mkdir(ca_path)

        ca_args = self._bunch_from_args(args, cluster_name)
        ca_args.path = ca_path

        ca_create_ca.Create(ca_args).execute(ca_args, False)
        ca_create_lb_agent.Create(ca_args).execute(ca_args, False)
        ca_create_web_admin.Create(ca_args).execute(ca_args, False)
        ca_create_scheduler.Create(ca_args).execute(ca_args, False)

        server_crypto_loc = {}

        for name in server_names:
            ca_args_server = deepcopy(ca_args)
            ca_args_server.server_name = server_names[name]
            ca_create_server.Create(ca_args_server).execute(
                ca_args_server, False)
            server_crypto_loc[name] = CryptoMaterialLocation(
                ca_path, '{}-{}'.format(cluster_name, server_names[name]))

        lb_agent_crypto_loc = CryptoMaterialLocation(ca_path, 'lb-agent')
        web_admin_crypto_loc = CryptoMaterialLocation(ca_path, 'web-admin')
        scheduler_crypto_loc = CryptoMaterialLocation(ca_path, 'scheduler1')

        self.logger.info('[{}/{}] Certificate authority created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 2) ODB
        #
        if create_odb.Create(args).execute(args,
                                           False) == self.SYS_ERROR.ODB_EXISTS:
            self.logger.info('[{}/{}] ODB schema already exists'.format(
                next_step.next(), total_steps))
        else:
            self.logger.info('[{}/{}] ODB schema created'.format(
                next_step.next(), total_steps))

# ################################################################################################################################

#
# 3) ODB initial data
#
        create_cluster_args = self._bunch_from_args(args, cluster_name)
        create_cluster_args.broker_host = broker_host
        create_cluster_args.broker_port = broker_port
        create_cluster_args.lb_host = lb_host
        create_cluster_args.lb_port = lb_port
        create_cluster_args.lb_agent_port = lb_agent_port
        create_cluster_args.admin_invoke_password = admin_invoke_password
        create_cluster.Create(create_cluster_args).execute(
            create_cluster_args, False)

        self.logger.info('[{}/{}] ODB initial data created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 4) servers
        #

        # Must be shared by all servers
        jwt_secret = Fernet.generate_key()
        secret_key = Fernet.generate_key()

        for idx, name in enumerate(server_names):
            server_path = os.path.join(args_path, server_names[name])
            os.mkdir(server_path)

            create_server_args = self._bunch_from_args(args, cluster_name)
            create_server_args.server_name = server_names[name]
            create_server_args.path = server_path
            create_server_args.cert_path = server_crypto_loc[name].cert_path
            create_server_args.pub_key_path = server_crypto_loc[name].pub_path
            create_server_args.priv_key_path = server_crypto_loc[
                name].priv_path
            create_server_args.ca_certs_path = server_crypto_loc[
                name].ca_certs_path
            create_server_args.jwt_secret = jwt_secret
            create_server_args.secret_key = secret_key

            server_id = create_server.Create(create_server_args).execute(
                create_server_args, next_port.next(), False, True)

            # We make the first server a delivery server for sample pub/sub topics.
            if idx == 0:
                self._set_pubsub_server(args, server_id, cluster_name,
                                        '/zato/demo/sample')

            self.logger.info('[{}/{}] server{} created'.format(
                next_step.next(), total_steps, name))

# ################################################################################################################################

#
# 5) load-balancer
#
        lb_path = os.path.join(args_path, 'load-balancer')
        os.mkdir(lb_path)

        create_lb_args = self._bunch_from_args(args, cluster_name)
        create_lb_args.path = lb_path
        create_lb_args.cert_path = lb_agent_crypto_loc.cert_path
        create_lb_args.pub_key_path = lb_agent_crypto_loc.pub_path
        create_lb_args.priv_key_path = lb_agent_crypto_loc.priv_path
        create_lb_args.ca_certs_path = lb_agent_crypto_loc.ca_certs_path

        # Need to substract 1 because we've already called .next() twice
        # when creating servers above.
        servers_port = next_port.next() - 1

        create_lb.Create(create_lb_args).execute(create_lb_args, True,
                                                 servers_port, False)
        self.logger.info('[{}/{}] Load-balancer created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 6) Web admin
        #
        web_admin_path = os.path.join(args_path, 'web-admin')
        os.mkdir(web_admin_path)

        create_web_admin_args = self._bunch_from_args(args, cluster_name)
        create_web_admin_args.path = web_admin_path
        create_web_admin_args.cert_path = web_admin_crypto_loc.cert_path
        create_web_admin_args.pub_key_path = web_admin_crypto_loc.pub_path
        create_web_admin_args.priv_key_path = web_admin_crypto_loc.priv_path
        create_web_admin_args.ca_certs_path = web_admin_crypto_loc.ca_certs_path
        create_web_admin_args.admin_invoke_password = admin_invoke_password

        web_admin_password = CryptoManager.generate_password()
        admin_created = create_web_admin.Create(create_web_admin_args).execute(
            create_web_admin_args, False, web_admin_password, True)

        # Need to reset the logger here because executing the create_web_admin command
        # loads the web admin's logger which doesn't like that of ours.
        self.reset_logger(args, True)
        self.logger.info('[{}/{}] Web admin created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 7) Scheduler
        #
        scheduler_path = os.path.join(args_path, 'scheduler')
        os.mkdir(scheduler_path)

        session = get_session(get_engine(args))

        with closing(session):
            cluster_id = session.query(Cluster.id).\
                filter(Cluster.name==cluster_name).\
                one()[0]

        create_scheduler_args = self._bunch_from_args(args, cluster_name)
        create_scheduler_args.path = scheduler_path
        create_scheduler_args.cert_path = scheduler_crypto_loc.cert_path
        create_scheduler_args.pub_key_path = scheduler_crypto_loc.pub_path
        create_scheduler_args.priv_key_path = scheduler_crypto_loc.priv_path
        create_scheduler_args.ca_certs_path = scheduler_crypto_loc.ca_certs_path
        create_scheduler_args.cluster_id = cluster_id

        create_scheduler.Create(create_scheduler_args).execute(
            create_scheduler_args, False, True)
        self.logger.info('[{}/{}] Scheduler created'.format(
            next_step.next(), total_steps))

        # ################################################################################################################################

        #
        # 8) Scripts
        #
        zato_bin = 'zato'
        zato_qs_start_path = os.path.join(args_path, 'zato-qs-start.sh')
        zato_qs_stop_path = os.path.join(args_path, 'zato-qs-stop.sh')
        zato_qs_restart_path = os.path.join(args_path, 'zato-qs-restart.sh')

        sanity_checks = []
        start_servers = []
        stop_servers = []

        for name in server_names:
            sanity_checks.append(
                sanity_checks_template.format(server_name=server_names[name]))
            start_servers.append(
                start_servers_template.format(server_name=server_names[name],
                                              step_number=int(name) + 3))
            stop_servers.append(
                stop_servers_template.format(server_name=server_names[name],
                                             step_number=int(name) + 1))

        sanity_checks = '\n'.join(sanity_checks)
        start_servers = '\n'.join(start_servers)
        stop_servers = '\n'.join(stop_servers)
        start_steps = 5 + servers
        stop_steps = 3 + servers

        zato_qs_start_head = zato_qs_start_head_template.format(
            zato_bin=zato_bin,
            script_dir=script_dir,
            cluster_name=cluster_name,
            start_steps=start_steps)
        zato_qs_start_body = zato_qs_start_body_template.format(
            sanity_checks=sanity_checks, start_servers=start_servers)
        zato_qs_start = zato_qs_start_head + zato_qs_start_body + zato_qs_start_tail

        zato_qs_stop = zato_qs_stop_template.format(zato_bin=zato_bin,
                                                    script_dir=script_dir,
                                                    cluster_name=cluster_name,
                                                    stop_steps=stop_steps,
                                                    stop_servers=stop_servers)

        open(zato_qs_start_path, 'w').write(zato_qs_start)
        open(zato_qs_stop_path, 'w').write(zato_qs_stop)
        open(zato_qs_restart_path, 'w').write(
            zato_qs_restart.format(script_dir=script_dir,
                                   cluster_name=cluster_name))

        file_mod = stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR | stat.S_IRGRP

        os.chmod(zato_qs_start_path, file_mod)
        os.chmod(zato_qs_stop_path, file_mod)
        os.chmod(zato_qs_restart_path, file_mod)

        self.logger.info('[{}/{}] Management scripts created'.format(
            next_step.next(), total_steps))
        self.logger.info('Quickstart cluster {} created'.format(cluster_name))

        if admin_created:
            self.logger.info('Web admin user:[admin], password:[{}]'.format(
                web_admin_password))
        else:
            self.logger.info('User [admin] already exists in the ODB')

        start_command = os.path.join(args_path, 'zato-qs-start.sh')
        self.logger.info('Start the cluster by issuing the {} command'.format(
            start_command))
        self.logger.info(
            'Visit https://zato.io/support for more information and support options'
        )
Beispiel #44
0
    def test_enrypt(self):
        """ Encrypt a message using the public key.
        """
        _plain_text = uuid4().hex

        with NamedTemporaryFile(prefix='zato-test-') as tf_priv:
            with NamedTemporaryFile(prefix='zato-test-') as tf_pub:

                tf_priv.write(priv_key)
                tf_priv.flush()

                tf_pub.write(pub_key)
                tf_pub.flush()

                cm_priv = CryptoManager()
                cm_priv.priv_key_location = tf_priv.name
                cm_priv.load_keys()

                cm_pub = CryptoManager()
                cm_pub.pub_key_location = tf_pub.name
                cm_pub.load_keys()

                encrypted = cm_pub.encrypt(_plain_text)
                decrypted = cm_priv.decrypt(encrypted)

                eq_(_plain_text, decrypted)
Beispiel #45
0
    def execute(self, args):

        repo_dir = os.path.join(
            os.path.abspath(os.path.join(self.original_dir, args.path)),
            'config', 'repo')
        config = get_config(repo_dir, 'server.conf')
        priv_key_location = os.path.abspath(
            os.path.join(repo_dir, config.crypto.priv_key_location))

        cm = CryptoManager(priv_key_location=priv_key_location)
        cm.load_keys()

        engine_args = Bunch()
        engine_args.odb_type = config.odb.engine
        engine_args.odb_user = config.odb.username
        engine_args.odb_password = cm.decrypt(config.odb.password)
        engine_args.odb_host = config.odb.host
        engine_args.odb_db_name = config.odb.db_name

        engine = self._get_engine(engine_args)
        session = self._get_session(engine)

        auth = None
        headers = {}

        with closing(session) as session:
            cluster = session.query(Server).\
                filter(Server.token == config.main.token).\
                one().cluster

            channel = session.query(HTTPSOAP).\
                filter(HTTPSOAP.cluster_id == cluster.id).\
                filter(HTTPSOAP.url_path == args.url_path).\
                one()

            if channel.security_id:
                security = session.query(HTTPBasicAuth).\
                    filter(HTTPBasicAuth.id == channel.security_id).\
                    first()

                if security:
                    auth = (security.username, security.password)

        if args.headers:
            for pair in args.headers.strip().split(';'):
                k, v = pair.strip().split('=', 1)
                headers[k] = v

        client = AnyServiceInvoker(
            'http://{}'.format(config.main.gunicorn_bind),
            args.url_path,
            auth,
            max_response_repr=int(args.max_response_repr),
            max_cid_repr=int(args.max_cid_repr))

        func = client.invoke_async if args. async else client.invoke
        response = func(args.name, args.payload, headers, args.channel,
                        args.data_format, args.transport)

        if response.ok:
            self.logger.info(response.data or '(None)')
        else:
            self.logger.error(response.details)

        if args.verbose:
            self.logger.debug('inner.text:[{}]'.format(response.inner.text))
            self.logger.debug('response:[{}]'.format(response))
Beispiel #46
0
 def crypto_manager(self):
     return CryptoManager()
Beispiel #47
0
 def execute(self, args):
     cm = CryptoManager(pub_key_location=os.path.abspath(args.path))
     cm.load_keys()
     
     self.logger.info('Encrypted value is [{}]'.format(cm.encrypt(args.secret)))
Beispiel #48
0
 def execute(self, args):
     cm = CryptoManager(priv_key_location=os.path.abspath(args.path))
     cm.load_keys()
     
     self.logger.info('Secret is [{}]'.format(cm.decrypt(args.secret)))