Example #1
0
    def _restore(self, data):
        """
        Helps restoring to reconnect the auto-connect connections smoothly on
        reload/restart of the app server..
        """
        # restore server version from flask session if flask server was
        # restarted. As we need server version to resolve sql template paths.
        masterpass_processed = process_masterpass_disabled()

        ServerManager._get_password_to_conn(data, masterpass_processed)
        # Get server type.
        self._get_server_type()

        # We need to know about the existing server variant supports during
        # first connection for identifications.
        self.pinged = datetime.datetime.now()
        try:
            if 'password' in data and data['password'] and \
                    hasattr(data['password'], 'encode'):
                data['password'] = data['password'].encode('utf-8')
            if 'tunnel_password' in data and data['tunnel_password']:
                data['tunnel_password'] = \
                    data['tunnel_password'].encode('utf-8')
        except Exception as e:
            current_app.logger.exception(e)

        connections = data['connections']

        for conn_id in connections:
            conn_info = connections[conn_id]
            if conn_info['conn_id'] in self.connections:
                conn = self.connections[conn_info['conn_id']]
            else:
                conn = self.connections[conn_info['conn_id']] = Connection(
                    self,
                    conn_info['conn_id'],
                    conn_info['database'],
                    auto_reconnect=conn_info['auto_reconnect'],
                    async_=conn_info['async_'],
                    use_binary_placeholder=conn_info['use_binary_placeholder'],
                    array_to_string=conn_info['array_to_string'])

            # only try to reconnect
            self._check_and_reconnect_server(conn, conn_info, data)
Example #2
0
def set_master_password():
    """
    Set the master password and store in the memory
    This password will be used to encrypt/decrypt saved server passwords
    """

    data = None

    if hasattr(request.data, 'decode'):
        data = request.data.decode('utf-8')

    if data != '':
        data = json.loads(data)

    # Master password is not applicable for server mode
    if not config.SERVER_MODE and config.MASTER_PASSWORD_REQUIRED:

        # if master pass is set previously
        if current_user.masterpass_check is not None and \
            data.get('button_click') and \
                not validate_master_password(data.get('password')):
            return form_master_password_response(
                existing=True,
                present=False,
                errmsg=gettext("Incorrect master password"))

        if data != '' and data.get('password', '') != '':

            # store the master pass in the memory
            set_crypt_key(data.get('password'))

            if current_user.masterpass_check is None:
                # master check is not set, which means the server password
                # data is old and is encrypted with old key
                # Re-encrypt with new key

                from pgadmin.browser.server_groups.servers.utils \
                    import reencrpyt_server_passwords
                reencrpyt_server_passwords(current_user.id,
                                           current_user.password,
                                           data.get('password'))

            # set the encrypted sample text with the new
            # master pass
            set_masterpass_check_text(data.get('password'))

        elif not get_crypt_key()[0] and \
                current_user.masterpass_check is not None:
            return form_master_password_response(
                existing=True,
                present=False,
            )
        elif not get_crypt_key()[0]:
            error_message = None
            if data.get('button_click') and data.get('password') == '':
                # If user attempted to enter a blank password, then throw error
                error_message = gettext("Master password cannot be empty")
            return form_master_password_response(existing=False,
                                                 present=False,
                                                 errmsg=error_message)

    # if master password is disabled now, but was used once then
    # remove all the saved passwords
    process_masterpass_disabled()

    if config.SERVER_MODE and current_user.masterpass_check is None:

        crypt_key = get_crypt_key()[1]
        from pgadmin.browser.server_groups.servers.utils \
            import reencrpyt_server_passwords
        reencrpyt_server_passwords(current_user.id, current_user.password,
                                   crypt_key)

        set_masterpass_check_text(crypt_key)

    return form_master_password_response(present=True, )
Example #3
0
    def _restore(self, data):
        """
        Helps restoring to reconnect the auto-connect connections smoothly on
        reload/restart of the app server..
        """
        # restore server version from flask session if flask server was
        # restarted. As we need server version to resolve sql template paths.
        masterpass_processed = process_masterpass_disabled()

        # The data variable is a copy so is not automatically synced
        # update here
        if masterpass_processed and 'password' in data:
            data['password'] = None
        if masterpass_processed and 'tunnel_password' in data:
            data['tunnel_password'] = None

        from pgadmin.browser.server_groups.servers.types import ServerType

        self.ver = data.get('ver', None)
        self.sversion = data.get('sversion', None)

        if self.ver and not self.server_type:
            for st in ServerType.types():
                if st.instanceOf(self.ver):
                    self.server_type = st.stype
                    self.server_cls = st
                    break

        # We need to know about the existing server variant supports during
        # first connection for identifications.
        self.pinged = datetime.datetime.now()
        try:
            if 'password' in data and data['password']:
                if hasattr(data['password'], 'encode'):
                    data['password'] = data['password'].encode('utf-8')
            if 'tunnel_password' in data and data['tunnel_password']:
                data['tunnel_password'] = \
                    data['tunnel_password'].encode('utf-8')
        except Exception as e:
            current_app.logger.exception(e)

        connections = data['connections']

        with connection_restore_lock:
            for conn_id in connections:
                conn_info = connections[conn_id]
                if conn_info['conn_id'] in self.connections:
                    conn = self.connections[conn_info['conn_id']]
                else:
                    conn = self.connections[conn_info['conn_id']] = Connection(
                        self,
                        conn_info['conn_id'],
                        conn_info['database'],
                        conn_info['auto_reconnect'],
                        conn_info['async_'],
                        use_binary_placeholder=conn_info[
                            'use_binary_placeholder'],
                        array_to_string=conn_info['array_to_string'])

                # only try to reconnect if connection was connected previously
                # and auto_reconnect is true.
                if conn_info['wasConnected'] and conn_info['auto_reconnect']:
                    try:
                        # Check SSH Tunnel needs to be created
                        if self.use_ssh_tunnel == 1 and \
                           not self.tunnel_created:
                            status, error = self.create_ssh_tunnel(
                                data['tunnel_password'])

                            # Check SSH Tunnel is alive or not.
                            self.check_ssh_tunnel_alive()

                        conn.connect(password=data['password'],
                                     server_types=ServerType.types())
                        # This will also update wasConnected flag in
                        # connection so no need to update the flag manually.
                    except CryptKeyMissing:
                        # maintain the status as this will help to restore once
                        # the key is available
                        conn.wasConnected = conn_info['wasConnected']
                        conn.auto_reconnect = conn_info['auto_reconnect']
                    except Exception as e:
                        current_app.logger.exception(e)
                        self.connections.pop(conn_info['conn_id'])
                        raise