예제 #1
0
def setup_default_plugins():
    # Copy default plugins into plugins folder
    if not os.path.exists(plugins.get_plugins_folder()):
        if os.path.exists(get_static_dir() + '/default-plugins/'):
            names = [f for f in os.listdir(get_static_dir() + '/default-plugins/')]
            try:
                shutil.copytree(
                    get_static_dir() + '/default-plugins/',
                    plugins.get_plugins_folder())
            except FileExistsError:
                pass

            # Enable plugins
            for name in names:
                if not name in plugins.get_enabled_plugins():
                    plugins.enable(name)

    for name in plugins.get_enabled_plugins():
        if not os.path.exists(plugins.get_plugin_data_folder(name)):
            try:
                os.mkdir(plugins.get_plugin_data_folder(name))
            except FileExistsError:
                pass
            except Exception as e:
                #logger.warn('Error enabling plugin: ' + str(e), terminal=True)
                plugins.disable(name, stop_event = False)
예제 #2
0
파일: __init__.py 프로젝트: x0rzkov/onionr
def register_plugin_commands(cmd) -> bool:
    plugin_cmd = plugin_command(cmd)
    for pl in onionrplugins.get_enabled_plugins():
        pl = onionrplugins.get_plugin(pl)
        if hasattr(pl, plugin_cmd):
            getattr(pl, plugin_cmd)(onionrpluginapi.PluginAPI)
            return True
    return False
예제 #3
0
파일: main.py 프로젝트: InvisaMage/onionr
 def __init__(self, apiInst):
     self.api = apiInst
     self.myCore = apiInst.get_core()
     self.shutdown = False
     self.running = 'undetermined'
     enabled = onionrplugins.get_enabled_plugins()
     self.mail_enabled = 'pms' in enabled
     self.flow_enabled = 'flow' in enabled
예제 #4
0
def load_plugin_blueprints(flaskapp, blueprint='flask_blueprint'):
    '''Iterate enabled plugins and load any http endpoints they have'''
    for plugin in onionrplugins.get_enabled_plugins():
        plugin = onionrplugins.get_plugin(plugin)
        try:
            flaskapp.register_blueprint(getattr(plugin, blueprint))
        except AttributeError:
            pass
예제 #5
0
def register_plugin_commands(cmd) -> bool:
    """Find a plugin command hook and execute it for a given cmd."""
    plugin_cmd = plugin_command(cmd)
    for pl in onionrplugins.get_enabled_plugins():
        pl = onionrplugins.get_plugin(pl)
        if hasattr(pl, plugin_cmd):
            getattr(pl, plugin_cmd)(onionrpluginapi.PluginAPI)
            return True
    return False
예제 #6
0
def event(event_name, data=None, onionr=None):
    '''
        Calls an event on all plugins (if defined)
    '''

    for plugin in plugins.get_enabled_plugins():
        try:
            call(plugins.get_plugin(plugin), event_name, data, onionr)
        except:
            logger.warn('Event \"' + event_name + '\" failed for plugin \"' +
                        plugin + '\".')
예제 #7
0
def load_plugin_security_whitelist_endpoints(whitelist: list):
    """Accept a list reference of whitelist endpoints from security/client.py and
    append plugin's specified endpoints to them by attribute"""
    for plugin in onionrplugins.get_enabled_plugins():
        try:
            plugin = onionrplugins.get_plugin(plugin)
        except FileNotFoundError:
            continue
        try:
            whitelist.extend(getattr(plugin, "security_whitelist"))
        except AttributeError:
            pass
예제 #8
0
파일: __init__.py 프로젝트: infoabcd/inti
def load_plugin_blueprints(flaskapp, blueprint: str = 'flask_blueprint'):
    """Iterate enabled plugins and load any http endpoints they have"""
    config.reload()
    disabled = config.get('plugins.disabled')
    for plugin in onionrplugins.get_enabled_plugins():
        if plugin in disabled:
            continue
        plugin = onionrplugins.get_plugin(plugin)
        try:
            flaskapp.register_blueprint(getattr(plugin, blueprint))
        except AttributeError:
            pass
예제 #9
0
def __event_caller(event_name, data = {}, onionr = None):
    '''
        DO NOT call this function, this is for threading code only.
        Instead, call onionrevents.event
    '''
    for plugin in plugins.get_enabled_plugins():
        try:
            call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(onionr, data))
        except ModuleNotFoundError as e:
            logger.warn('Disabling nonexistant plugin "%s"...' % plugin)
            plugins.disable(plugin, onionr, stop_event = False)
        except Exception as e:
            logger.warn('Event "%s" failed for plugin "%s".' % (event_name, plugin))
            logger.debug(str(e))
예제 #10
0
def __event_caller(event_name, data = {}):
    '''
        DO NOT call this function, this is for threading code only.
        Instead, call onionrevents.event
    '''
    disabled = config.get('plugins.disabled')
    for plugin in plugins.get_enabled_plugins():
        if plugin in disabled: continue
        try:
            call(plugins.get_plugin(plugin), event_name, data, get_pluginapi(data))
        except ModuleNotFoundError as e:
            logger.warn('Disabling nonexistant plugin "%s"...' % plugin, terminal=True)
            plugins.disable(plugin, stop_event = False)
        except Exception as e:
            logger.warn('Event "%s" failed for plugin "%s".' % (event_name, plugin), terminal=True)
            logger.debug((event_name + ' - ' + plugin + ' - ' + str(e)), terminal=True)
예제 #11
0
파일: __init__.py 프로젝트: x0rzkov/onionr
    def get_help_message(cmd: str,
                         default: str = 'No help available for this command'):
        """Return help message for a given command, supports plugin commands"""
        pl_cmd = plugin_command(cmd)
        for pl in onionrplugins.get_enabled_plugins():
            pl = onionrplugins.get_plugin(pl)
            if hasattr(pl, pl_cmd):
                try:
                    return getattr(pl, pl_cmd).onionr_help
                except AttributeError:
                    pass

        for i in arguments.get_arguments():
            for alias in i:
                try:
                    return arguments.get_help(cmd)
                except AttributeError:
                    pass
        return default  # Return the help string
예제 #12
0
파일: __init__.py 프로젝트: x0rzkov/onionr
def register():
    """Registers commands and handles help command processing"""
    def get_help_message(cmd: str,
                         default: str = 'No help available for this command'):
        """Return help message for a given command, supports plugin commands"""
        pl_cmd = plugin_command(cmd)
        for pl in onionrplugins.get_enabled_plugins():
            pl = onionrplugins.get_plugin(pl)
            if hasattr(pl, pl_cmd):
                try:
                    return getattr(pl, pl_cmd).onionr_help
                except AttributeError:
                    pass

        for i in arguments.get_arguments():
            for alias in i:
                try:
                    return arguments.get_help(cmd)
                except AttributeError:
                    pass
        return default  # Return the help string

    PROGRAM_NAME = "onionr"

    # Get the command
    try:
        cmd = sys.argv[1]
    except IndexError:
        logger.debug("Detected Onionr run with no commands specified")
        return

    is_help_cmd = False
    if cmd.replace('--', '').lower() == 'help': is_help_cmd = True

    try:
        try:
            if not cmd in ('start', 'details', 'show-details'):
                os.chdir(os.environ['ORIG_ONIONR_RUN_DIR'])
        except KeyError:
            pass
        try:
            arguments.get_func(cmd)()
        except KeyboardInterrupt:
            pass
    except onionrexceptions.NotFound:
        if not register_plugin_commands(cmd) and not is_help_cmd:
            recommend.recommend()
            sys.exit(3)

    if is_help_cmd:
        try:
            sys.argv[2]
        except IndexError:
            for i in arguments.get_arguments():
                logger.info(
                    '%s <%s>: %s' %
                    (PROGRAM_NAME, '/'.join(i), get_help_message(i[0])),
                    terminal=True)
            for pl in onionrplugins.get_enabled_plugins():
                pl = onionrplugins.get_plugin(pl)
                if hasattr(pl, 'ONIONR_COMMANDS'):
                    print('')
                    try:
                        logger.info('%s commands:' % (pl.plugin_name, ),
                                    terminal=True)
                    except AttributeError:
                        logger.info('%s commands:' % (pl.__name__, ),
                                    terminal=True)
                    for plugin_cmd in pl.ONIONR_COMMANDS:
                        logger.info('%s %s: %s' %
                                    (PROGRAM_NAME, plugin_cmd,
                                     get_help_message(plugin_cmd)),
                                    terminal=True)
                    print('')
        else:
            try:
                logger.info(
                    '%s %s: %s' %
                    (PROGRAM_NAME, sys.argv[2], get_help_message(sys.argv[2])),
                    terminal=True)
            except KeyError:
                logger.error('%s: command does not exist.' % [sys.argv[2]],
                             terminal=True)
                sys.exit(3)
        return
예제 #13
0
def register():
    """Register commands and handles help command processing."""
    def get_help_message(cmd: str,
                         default: str = 'No help available for this command'):
        """Print help message for a given command, supports plugin commands."""
        pl_cmd = plugin_command(cmd)
        for pl in onionrplugins.get_enabled_plugins():
            pl = onionrplugins.get_plugin(pl)
            if hasattr(pl, pl_cmd):
                try:
                    return getattr(pl, pl_cmd).onionr_help
                except AttributeError:
                    pass

        for i in arguments.get_arguments():
            for _ in i:
                try:
                    return arguments.get_help(cmd)
                except AttributeError:
                    pass
        return default  # Return the help string

    PROGRAM_NAME = "onionr"

    # Get the command
    try:
        cmd = sys.argv[1]
    except IndexError:
        logger.info('Run with --help to see available commands', terminal=True)
        sys.exit(10)

    is_help_cmd = False
    if cmd.replace('--', '').lower() == 'help':
        is_help_cmd = True

    try:
        try:
            arguments.get_func(cmd)()
        except KeyboardInterrupt:
            pass
    except onionrexceptions.NotFound:
        if not register_plugin_commands(cmd) and not is_help_cmd:
            recommend.recommend()
            sys.exit(3)

    if is_help_cmd:
        try:
            sys.argv[2]
        except IndexError:
            for i in arguments.get_arguments():
                _show_term('%s <%s>: %s' %
                           (PROGRAM_NAME, '/'.join(i), get_help_message(i[0])))
            for pl in onionrplugins.get_enabled_plugins():
                pl = onionrplugins.get_plugin(pl)
                if hasattr(pl, 'ONIONR_COMMANDS'):
                    print('')
                    try:
                        _show_term('%s commands:' % (pl.plugin_name, ))
                    except AttributeError:
                        _show_term('%s commands:' % (pl.__name__, ))
                    for plugin_cmd in pl.ONIONR_COMMANDS:
                        _show_term(
                            '%s %s: %s' % (PROGRAM_NAME, plugin_cmd,
                                           get_help_message(plugin_cmd)), )
                    print('')
        else:
            try:
                _show_term(
                    '%s %s: %s' %
                    (PROGRAM_NAME, sys.argv[2], get_help_message(sys.argv[2])))
            except KeyError:
                logger.error('%s: command does not exist.' % [sys.argv[2]],
                             terminal=True)
                sys.exit(3)
        return
예제 #14
0
    def __init__(self):
        '''
            Main Onionr class. This is for the CLI program, and does not handle much of the logic.
            In general, external programs and plugins should not use this class.
        '''

        try:
            os.chdir(sys.path[0])
        except FileNotFoundError:
            pass

        # Load global configuration data

        data_exists = os.path.exists('data/')

        if not data_exists:
            os.mkdir('data/')

        if os.path.exists('static-data/default_config.json'):
            config.set_config(
                json.loads(open('static-data/default_config.json').read())
            )  # this is the default config, it will be overwritten if a config file already exists. Else, it saves it
        else:
            # the default config file doesn't exist, try hardcoded config
            config.set_config({
                'devmode': True,
                'log': {
                    'file': {
                        'output': True,
                        'path': 'data/output.log'
                    },
                    'console': {
                        'output': True,
                        'color': True
                    }
                }
            })
        if not data_exists:
            config.save()
        config.reload()  # this will read the configuration file into memory

        settings = 0b000
        if config.get('log', {'console': {'color': True}})['console']['color']:
            settings = settings | logger.USE_ANSI
        if config.get('log', {'console': {
                'output': True
        }})['console']['output']:
            settings = settings | logger.OUTPUT_TO_CONSOLE
        if config.get('log', {'file': {'output': True}})['file']['output']:
            settings = settings | logger.OUTPUT_TO_FILE
            logger.set_file(
                config.get('log', {'file': {
                    'path': 'data/output.log'
                }})['file']['path'])
        logger.set_settings(settings)

        if str(config.get('devmode', True)).lower() == 'true':
            self._developmentMode = True
            logger.set_level(logger.LEVEL_DEBUG)
        else:
            self._developmentMode = False
            logger.set_level(logger.LEVEL_INFO)

        self.onionrCore = core.Core()
        self.onionrUtils = OnionrUtils(self.onionrCore)

        # Handle commands

        self.debug = False  # Whole application debugging

        if os.path.exists('data-encrypted.dat'):
            while True:
                print('Enter password to decrypt:')
                password = getpass.getpass()
                result = self.onionrCore.dataDirDecrypt(password)
                if os.path.exists('data/'):
                    break
                else:
                    logger.error('Failed to decrypt: ' + result[1],
                                 timestamp=False)
        else:
            # If data folder does not exist
            if not data_exists:
                if not os.path.exists('data/blocks/'):
                    os.mkdir('data/blocks/')

            # Copy default plugins into plugins folder
            if not os.path.exists(plugins.get_plugins_folder()):
                if os.path.exists('static-data/default-plugins/'):
                    names = [
                        f for f in os.listdir("static-data/default-plugins/")
                        if not os.path.isfile(f)
                    ]
                    shutil.copytree('static-data/default-plugins/',
                                    plugins.get_plugins_folder())

                    # Enable plugins
                    for name in names:
                        if not name in plugins.get_enabled_plugins():
                            plugins.enable(name, self)

        for name in plugins.get_enabled_plugins():
            if not os.path.exists(plugins.get_plugin_data_folder(name)):
                try:
                    os.mkdir(plugins.get_plugin_data_folder(name))
                except:
                    plugins.disable(name, onionr=self, stop_event=False)

        if not os.path.exists(self.onionrCore.peerDB):
            self.onionrCore.createPeerDB()
            pass
        if not os.path.exists(self.onionrCore.addressDB):
            self.onionrCore.createAddressDB()

        # Get configuration

        if not data_exists:
            # Generate default config
            # Hostname should only be set if different from 127.x.x.x. Important for DNS rebinding attack prevention.
            if self.debug:
                randomPort = 8080
            else:
                while True:
                    randomPort = random.randint(1024, 65535)
                    if self.onionrUtils.checkPort(randomPort):
                        break
            config.set(
                'client', {
                    'participate': 'true',
                    'client_hmac': base64.b16encode(
                        os.urandom(32)).decode('utf-8'),
                    'port': randomPort,
                    'api_version': API_VERSION
                }, True)

        self.cmds = {
            '': self.showHelpSuggestion,
            'help': self.showHelp,
            'version': self.version,
            'config': self.configure,
            'start': self.start,
            'stop': self.killDaemon,
            'status': self.showStats,
            'statistics': self.showStats,
            'stats': self.showStats,
            'enable-plugin': self.enablePlugin,
            'enplugin': self.enablePlugin,
            'enableplugin': self.enablePlugin,
            'enmod': self.enablePlugin,
            'disable-plugin': self.disablePlugin,
            'displugin': self.disablePlugin,
            'disableplugin': self.disablePlugin,
            'dismod': self.disablePlugin,
            'reload-plugin': self.reloadPlugin,
            'reloadplugin': self.reloadPlugin,
            'reload-plugins': self.reloadPlugin,
            'reloadplugins': self.reloadPlugin,
            'create-plugin': self.createPlugin,
            'createplugin': self.createPlugin,
            'plugin-create': self.createPlugin,
            'listkeys': self.listKeys,
            'list-keys': self.listKeys,
            'addmsg': self.addMessage,
            'addmessage': self.addMessage,
            'add-msg': self.addMessage,
            'add-message': self.addMessage,
            'pm': self.sendEncrypt,
            'getpms': self.getPMs,
            'get-pms': self.getPMs,
            'addpeer': self.addPeer,
            'add-peer': self.addPeer,
            'add-address': self.addAddress,
            'add-addr': self.addAddress,
            'addaddr': self.addAddress,
            'addaddress': self.addAddress,
            'addfile': self.addFile,
            'importblocks': self.onionrUtils.importNewBlocks,
            'introduce': self.onionrCore.introduceNode,
            'connect': self.addAddress
        }

        self.cmdhelp = {
            'help': 'Displays this Onionr help menu',
            'version': 'Displays the Onionr version',
            'config': 'Configures something and adds it to the file',
            'start': 'Starts the Onionr daemon',
            'stop': 'Stops the Onionr daemon',
            'stats': 'Displays node statistics',
            'enable-plugin': 'Enables and starts a plugin',
            'disable-plugin': 'Disables and stops a plugin',
            'reload-plugin': 'Reloads a plugin',
            'create-plugin': 'Creates directory structure for a plugin',
            'add-peer': 'Adds a peer to database',
            'list-peers': 'Displays a list of peers',
            'add-msg': 'Broadcasts a message to the Onionr network',
            'pm': 'Adds a private message to block',
            'get-pms': 'Shows private messages sent to you',
            'addfile': 'Create an Onionr block from a file',
            'importblocks':
            'import blocks from the disk (Onionr is transport-agnostic!)',
            'introduce': 'Introduce your node to the public Onionr network',
        }

        # initialize plugins
        events.event('init', onionr=self, threaded=False)

        command = ''
        try:
            command = sys.argv[1].lower()
        except IndexError:
            command = ''
        finally:
            self.execute(command)

        if not self._developmentMode:
            encryptionPassword = self.onionrUtils.getPassword(
                'Enter password to encrypt directory: ')
            self.onionrCore.dataDirEncrypt(encryptionPassword)
            shutil.rmtree('data/')

        return
예제 #15
0
파일: onionr.py 프로젝트: InvisaMage/onionr
    def __init__(self):
        '''
            Main Onionr class. This is for the CLI program, and does not handle much of the logic.
            In general, external programs and plugins should not use this class.
        '''
        self.userRunDir = os.getcwd() # Directory user runs the program from
        self.killed = False

        if sys.argv[0] == os.path.basename(__file__):
            try:
                os.chdir(sys.path[0])
            except FileNotFoundError:
                pass

        # set data dir
        self.dataDir = os.environ.get('ONIONR_HOME', os.environ.get('DATA_DIR', 'data/'))
        if not self.dataDir.endswith('/'):
            self.dataDir += '/'

        # set log file
        logger.set_file(os.environ.get('LOG_DIR', 'data') + '/onionr.log')

        # Load global configuration data
        data_exists = Onionr.setupConfig(self.dataDir, self)

        if netcontroller.torBinary() is None:
            logger.error('Tor is not installed')
            sys.exit(1)

        # If block data folder does not exist
        if not os.path.exists(self.dataDir + 'blocks/'):
            os.mkdir(self.dataDir + 'blocks/')

        # Copy default plugins into plugins folder
        if not os.path.exists(plugins.get_plugins_folder()):
            if os.path.exists('static-data/default-plugins/'):
                names = [f for f in os.listdir("static-data/default-plugins/")]
                shutil.copytree('static-data/default-plugins/', plugins.get_plugins_folder())

                # Enable plugins
                for name in names:
                    if not name in plugins.get_enabled_plugins():
                        plugins.enable(name, self)

        for name in plugins.get_enabled_plugins():
            if not os.path.exists(plugins.get_plugin_data_folder(name)):
                try:
                    os.mkdir(plugins.get_plugin_data_folder(name))
                except:
                    plugins.disable(name, onionr = self, stop_event = False)

        self.communicatorInst = None
        self.onionrCore = core.Core()
        self.onionrCore.onionrInst = self
        #self.deleteRunFiles()
        self.onionrUtils = onionrutils.OnionrUtils(self.onionrCore)

        self.clientAPIInst = '' # Client http api instance
        self.publicAPIInst = '' # Public http api instance

        signal.signal(signal.SIGTERM, self.exitSigterm)

        # Handle commands

        self.debug = False # Whole application debugging

        # Get configuration
        if type(config.get('client.webpassword')) is type(None):
            config.set('client.webpassword', base64.b16encode(os.urandom(32)).decode('utf-8'), savefile=True)
        if type(config.get('client.client.port')) is type(None):
            randomPort = netcontroller.getOpenPort()
            config.set('client.client.port', randomPort, savefile=True)
        if type(config.get('client.public.port')) is type(None):
            randomPort = netcontroller.getOpenPort()
            config.set('client.public.port', randomPort, savefile=True)
        if type(config.get('client.api_version')) is type(None):
            config.set('client.api_version', API_VERSION, savefile=True)

        self.cmds = commands.get_commands(self)
        self.cmdhelp = commands.cmd_help

        # initialize plugins
        events.event('init', onionr = self, threaded = False)

        command = ''
        try:
            command = sys.argv[1].lower()
        except IndexError:
            command = ''
        finally:
            self.execute(command)

        return