Skip to content

Commit

Permalink
make arsenal user configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
jubeaz committed May 24, 2024
1 parent f5948bb commit 20474b2
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 71 deletions.
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ This project is inspired by navi (<https://github.com/denisidoro/navi>) because
- Add yml support (thx @0xswitch )
- Add fzf support with ctrl+t (thx @mgp25)
- Add prefix to commands generated (with -f)
- Add user config file (genrated at first run in ~/.arsenal.conf)

## Install & Launch
- with pip :
Expand Down Expand Up @@ -81,19 +82,17 @@ yay -S arsenal
./run -t -e # just like the -t mode but with direct execution in the other pane without quitting arsenal
```

## Edit config file

When arsenal is run if `~/.arsenal.comf` does not exist a copy of `<arsenal_home>/data/arsenal.conf` is made.

## Add external cheatsheets

You could add your own cheatsheets insode the my_cheats folder or in the ~/.cheats folder.
You could add your own cheatsheets by referencing them in your `.arsenal.conf`

You could also add additional paths to the file `<arsenal_home>/arsenal/modules/config.py`,
arsenal reads `.md` (MarkDown) and `.rst` (RestructuredText).
If in `.arsenal.conf` you set `use_builtin_cheats` to `yes` your cheats will will be mered with cheats defined in `<arsenal_home>/data/cheats`

```
CHEATS_PATHS = [
join(BASEPATH, "cheats"), # DEFAULT
join(HOMEPATH, "docs/my_cheats")
]
```
arsenal reads `.md` (MarkDown) and `.rst` (RestructuredText).

Cheatsheets examples are in `<arsenal_home>/cheats`: `README.md` and `README.rst`

Expand Down
4 changes: 3 additions & 1 deletion arsenal/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import termios
import re
import time
from shutil import copy
from curses import wrapper

# arsenal
Expand Down Expand Up @@ -59,7 +60,6 @@ def run(self):
# load cheatsheets
cheatsheets = cheat.Cheats().read_files(config.CHEATS_PATHS, config.FORMATS,
config.EXCLUDE_LIST)

if args.check:
check.check(cheatsheets)
else:
Expand Down Expand Up @@ -194,6 +194,8 @@ def prefil_shell_cmd(self, cmd):


def main():
if not os.path.exists(config.CONFIG_PATH):
copy(config.DEFAULT_CONFIG_PATH, config.CONFIG_PATH)
try:
App().run()
except KeyboardInterrupt:
Expand Down
34 changes: 34 additions & 0 deletions arsenal/data/arsenal.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[arsenal]
fuzzing_dirs = ["/usr/local/share/wordlists/**/*.txt"]
use_builtin_cheats = yes
user_cheats_paths = ["~/.cheats"]
formats = ["md", "rst", "yml"]
exclude_list = ["README.md", "README.rst", "index.rst"]
savevarfile = "~/.arsenal.json"
prefix_globalvar_name = "arsenal_prefix_cmd"



[colors]
basic_color = 0
col1_color = 7
; gold
col2_color = 4
; purple light
col3_color = 14
; 26 ; violet clair: 14 ; 4 yellow ; 6 purple ; 7 cyan ; 9 dark grey
col4_color = 5
; blue
col5_color = 5
; output std invert
col1_color_select = 256
col2_color_select = 256
col3_color_select = 256
col4_color_select = 256
; background red
cursor_color_select = 266
prompt_color = 0
info_name_color = 4
info_desc_color = 0
info_cmd_color = 0
arg_name_color = 5
71 changes: 58 additions & 13 deletions arsenal/modules/config.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,72 @@
import configparser
import os
from os.path import dirname, abspath, expanduser, join
from ast import literal_eval

# Base paths
DATAPATH = join(dirname(dirname(abspath(__file__))), 'data')
BASEPATH = dirname(dirname(dirname(abspath(__file__))))
DEFAULT_CONFIG_PATH = join(DATAPATH, "arsenal.conf")
CONFIG_PATH = expanduser("~/.arsenal.conf")
HOMEPATH = expanduser("~")
FORMATS = ["md", "rst", "yml"]
EXCLUDE_LIST = ["README.md", "README.rst", "index.rst"]
FUZZING_DIRS = ["/usr/local/share/wordlists/**/*.txt"]

CHEATS_PATHS = [
join(DATAPATH, "cheats"), # DEFAULT
# Additional paths below, add comma to line above
join(BASEPATH, "my_cheats"),
join(HOMEPATH, ".cheats")
]

DEFAULT_CHEATS_PATHS = [join(DATAPATH, "cheats")]
messages_error_missing_arguments = 'Error missing arguments'

# set lower delay to use ESC key (in ms)
os.environ.setdefault('ESCDELAY', '25')
os.environ['TERM'] = 'xterm-256color'

savevarfile = join(HOMEPATH, ".arsenal.json")
arsenal_default_config = configparser.ConfigParser()
arsenal_default_config.read(DEFAULT_CONFIG_PATH)

arsenal_config = configparser.ConfigParser()
arsenal_config.read(CONFIG_PATH)


# Update config in case default have been extended or use has
# removed requiered
config_updated = False
for section in arsenal_default_config.sections():
if not arsenal_config.has_section(section):
arsenal_config.add_section(section)
config_updated = True
for option in arsenal_default_config.options(section):
if not arsenal_config.has_option(section, option):
config_updated = True
arsenal_config.set(section, option, arsenal_default_config.get(section, option))

if config_updated:
with open(CONFIG_PATH, "w") as config_file:
arsenal_config.write(config_file)

CHEATS_PATHS= []
use_builtin_cheats = arsenal_config.getboolean("arsenal", "use_builtin_cheats")
user_cheats_paths = literal_eval(arsenal_config.get("arsenal", "user_cheats_paths"))

for p in user_cheats_paths:
CHEATS_PATHS.append(expanduser(p))
if use_builtin_cheats:
CHEATS_PATHS += DEFAULT_CHEATS_PATHS

savevarfile = arsenal_config.get("arsenal", "savevarfile")
FORMATS = literal_eval(arsenal_config.get("arsenal", "formats"))
EXCLUDE_LIST = literal_eval(arsenal_config.get("arsenal", "exclude_list"))
FUZZING_DIRS = literal_eval(arsenal_config.get("arsenal", "fuzzing_dirs"))
PREFIX_GLOBALVAR_NAME = arsenal_config.get("arsenal", "prefix_globalvar_name")

PREFIX_GLOBALVAR_NAME = "arsenal_prefix_cmd"
BASIC_COLOR = arsenal_config.getint("colors", "basic_color")
COL1_COLOR = arsenal_config.getint("colors", "col1_color")
COL2_COLOR = arsenal_config.getint("colors", "col2_color")
COL3_COLOR = arsenal_config.getint("colors", "col3_color")
COL4_COLOR = arsenal_config.getint("colors", "col4_color")
COL5_COLOR = arsenal_config.getint("colors", "col5_color")
COL1_COLOR_SELECT = arsenal_config.getint("colors", "col1_color_select")
COL2_COLOR_SELECT = arsenal_config.getint("colors", "col2_color_select")
COL3_COLOR_SELECT = arsenal_config.getint("colors", "col3_color_select")
COL4_COLOR_SELECT = arsenal_config.getint("colors", "col4_color_select")
CURSOR_COLOR_SELECT = arsenal_config.getint("colors", "cursor_color_select")
PROMPT_COLOR = arsenal_config.getint("colors", "prompt_color")
INFO_NAME_COLOR = arsenal_config.getint("colors", "info_name_color")
INFO_DESC_COLOR = arsenal_config.getint("colors", "info_desc_color")
INFO_CMD_COLOR = arsenal_config.getint("colors", "info_cmd_color")
ARG_NAME_COLOR = arsenal_config.getint("colors", "arg_name_color")
79 changes: 31 additions & 48 deletions arsenal/modules/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ def draw_prompt():
ncols, nlines = 5, 1
promptwin = curses.newwin(nlines, ncols, y, x)
try:
promptwin.addstr("\u2620 >", curses.color_pair(Gui.BASIC_COLOR))
promptwin.addstr("\u2620 >", curses.color_pair(config.BASIC_COLOR))
except:
promptwin.addstr(">>>>", curses.color_pair(Gui.BASIC_COLOR))
promptwin.addstr(">>>>", curses.color_pair(config.BASIC_COLOR))
promptwin.refresh()
return promptwin

Expand All @@ -53,11 +53,11 @@ def draw_infobox(self):
selected_cheat = self.selected_cheat()
if selected_cheat is not None:
infowin.addstr(y + 1, x + 2, Gui.draw_string(selected_cheat.name, self.width - 3),
curses.color_pair(Gui.INFO_NAME_COLOR))
curses.color_pair(config.INFO_NAME_COLOR))
# infowin.addstr(y + 2, x + 2, Gui.draw_string(selected_cheat.description.split('\n')[0], self.width - 3),
# curses.color_pair(Gui.INFO_DESC_COLOR))
# curses.color_pair(config.INFO_DESC_COLOR))
infowin.addstr(y + 2, x + 2, Gui.draw_string(selected_cheat.printable_command, self.width - 3),
curses.color_pair(Gui.INFO_CMD_COLOR))
curses.color_pair(config.INFO_CMD_COLOR))
infowin.border()
infowin.refresh()
return infowin
Expand All @@ -69,7 +69,7 @@ def draw_editbox(self):
y, x = 5, 6
ncols, nlines = self.width - 5, 1
editwin = curses.newwin(nlines, ncols, y, x)
editwin.addstr(self.input_buffer, curses.color_pair(Gui.BASIC_COLOR))
editwin.addstr(self.input_buffer, curses.color_pair(config.BASIC_COLOR))
editwin.refresh()
return editwin

Expand All @@ -96,34 +96,34 @@ def draw_cheat(win, cheat, selected):
tags = cheat.get_tags()

if selected:
win.addstr(prompt, curses.color_pair(Gui.CURSOR_COLOR_SELECT))
win.addstr(prompt, curses.color_pair(config.CURSOR_COLOR_SELECT))
win.addstr("{:{}s}".format(Gui.draw_string(tags, col4_size), col4_size),
curses.color_pair(Gui.COL4_COLOR_SELECT))
curses.color_pair(config.COL4_COLOR_SELECT))
win.addstr("{:{}s}".format(Gui.draw_string(cheat.str_title, col3_size), col3_size),
curses.color_pair(Gui.COL3_COLOR_SELECT))
curses.color_pair(config.COL3_COLOR_SELECT))
win.addstr("{:{}s}".format(Gui.draw_string(cheat.name, col1_size), col1_size),
curses.color_pair(Gui.COL2_COLOR_SELECT))
curses.color_pair(config.COL2_COLOR_SELECT))
win.addstr("{:{}s}".format(Gui.draw_string(cheat.printable_command, col2_size), col2_size),
curses.color_pair(Gui.COL3_COLOR_SELECT))
curses.color_pair(config.COL3_COLOR_SELECT))
# win.addstr("{:{}s}".format(Gui.draw_string(title, col0_size), col0_size),
# curses.color_pair(Gui.COL1_COLOR_SELECT))
# curses.color_pair(config.COL1_COLOR_SELECT))
win.addstr("\n")
else:
win.addstr(' ' * len(prompt), curses.color_pair(Gui.BASIC_COLOR))
win.addstr(' ' * len(prompt), curses.color_pair(config.BASIC_COLOR))
if tags.startswith('[W]'):
win.addstr("{:{}s}".format(Gui.draw_string(tags, col4_size), col4_size),
curses.color_pair(Gui.COL5_COLOR))
curses.color_pair(config.COL5_COLOR))
else:
win.addstr("{:{}s}".format(Gui.draw_string(tags, col4_size), col4_size),
curses.color_pair(Gui.COL4_COLOR))
curses.color_pair(config.COL4_COLOR))
win.addstr("{:{}s}".format(Gui.draw_string(cheat.str_title, col3_size), col3_size),
curses.color_pair(Gui.COL1_COLOR))
curses.color_pair(config.COL1_COLOR))
win.addstr("{:{}s}".format(Gui.draw_string(cheat.name, col1_size), col1_size),
curses.color_pair(Gui.COL2_COLOR))
curses.color_pair(config.COL2_COLOR))
win.addstr("{:{}s}".format(Gui.draw_string(cheat.printable_command, col2_size), col2_size),
curses.color_pair(Gui.COL3_COLOR))
curses.color_pair(config.COL3_COLOR))
# win.addstr("{:{}s}".format(Gui.draw_string(title, col0_size), col0_size),
# curses.color_pair(Gui.COL1_COLOR))
# curses.color_pair(config.COL1_COLOR))
win.addstr("\n")

def draw_cheatslistbox(self):
Expand Down Expand Up @@ -153,7 +153,7 @@ def draw_footbox(self, info):

# print nb cmd info (bottom left)
nbinfowin = curses.newwin(nlines, ncols, y, x)
nbinfowin.addstr(info, curses.color_pair(Gui.BASIC_COLOR))
nbinfowin.addstr(info, curses.color_pair(config.BASIC_COLOR))
nbinfowin.refresh()

# print cheatsheet filename (bottom right)
Expand All @@ -165,7 +165,7 @@ def draw_footbox(self, info):
cheat_file = cheat_file[0:self.width - 17] + ".."

fileinfowin = curses.newwin(nlines, ncols, y, self.width - (len(cheat_file) + 3))
fileinfowin.addstr(cheat_file, curses.color_pair(Gui.BASIC_COLOR))
fileinfowin.addstr(cheat_file, curses.color_pair(config.BASIC_COLOR))
fileinfowin.refresh()

def match(self, cheat):
Expand Down Expand Up @@ -507,9 +507,9 @@ def draw_selected_arg(self, y_pos):
arg_name, arg_value = Gui.cmd.get_arg(self.current_arg)
max_size = self.max_preview_size - 4 - len(arg_name)
selectedargline = curses.newwin(nlines, ncols, y, x)
selectedargline.addstr(" > ", curses.color_pair(Gui.BASIC_COLOR))
selectedargline.addstr(arg_name, curses.color_pair(Gui.ARG_NAME_COLOR))
selectedargline.addstr(" = " + Gui.draw_string(arg_value, max_size), curses.color_pair(Gui.BASIC_COLOR))
selectedargline.addstr(" > ", curses.color_pair(config.BASIC_COLOR))
selectedargline.addstr(arg_name, curses.color_pair(config.ARG_NAME_COLOR))
selectedargline.addstr(" = " + Gui.draw_string(arg_value, max_size), curses.color_pair(config.BASIC_COLOR))
selectedargline.refresh()

def draw_args_list(self, y_pos):
Expand All @@ -522,7 +522,7 @@ def draw_args_list(self, y_pos):
for arg_name, arg_data in Gui.cmd.args.items():
max_size = self.max_preview_size + 4
argline = Gui.draw_string(f" {arg_name} = {arg_data["value"]}", max_size) + "\n"
argwin.addstr(argline, curses.color_pair(Gui.BASIC_COLOR))
argwin.addstr(argline, curses.color_pair(config.BASIC_COLOR))
argwin.refresh()

def draw_desc_preview(self, argprev, p_x, p_y, description_lines):
Expand All @@ -531,10 +531,10 @@ def draw_desc_preview(self, argprev, p_x, p_y, description_lines):
"""
# draw description
if len(description_lines) > 0:
argprev.addstr(p_y, p_x, "-----", curses.color_pair(Gui.BASIC_COLOR))
argprev.addstr(p_y, p_x, "-----", curses.color_pair(config.BASIC_COLOR))
p_y += 1
for description_line in description_lines:
argprev.addstr(p_y, p_x, description_line, curses.color_pair(Gui.BASIC_COLOR))
argprev.addstr(p_y, p_x, description_line, curses.color_pair(config.BASIC_COLOR))
p_y += 1
p_y += 1
argprev.refresh()
Expand All @@ -548,12 +548,12 @@ def draw_cmd_preview(self, argprev, p_x, p_y=1):
cmdparts = Gui.cmd.get_command_parts()

# draw command
argprev.addstr(p_y, p_x, "$ ", curses.color_pair(Gui.BASIC_COLOR))
argprev.addstr(p_y, p_x, "$ ", curses.color_pair(config.BASIC_COLOR))
# draw preview cmdline
for i in range(len(cmdparts) + Gui.cmd.nb_place_holder):
if i % 2 == 0:
# draw cmd parts in white
self.draw_preview_part(argprev, cmdparts[i // 2], curses.color_pair(Gui.BASIC_COLOR))
self.draw_preview_part(argprev, cmdparts[i // 2], curses.color_pair(config.BASIC_COLOR))
else:
arg_name, arg_value = Gui.cmd.get_arg((i - 1) // 2)
if arg_value == "":
Expand All @@ -566,10 +566,10 @@ def draw_cmd_preview(self, argprev, p_x, p_y=1):
# draw argument
if self.current_arg_name == arg_name:
# if arg is selected print in blue COL1_COLOR
self.draw_preview_part(argprev, arg, curses.color_pair(Gui.ARG_NAME_COLOR))
self.draw_preview_part(argprev, arg, curses.color_pair(config.ARG_NAME_COLOR))
else:
# else in white
self.draw_preview_part(argprev, arg, curses.color_pair(Gui.BASIC_COLOR))
self.draw_preview_part(argprev, arg, curses.color_pair(config.BASIC_COLOR))
argprev.border()
argprev.refresh()

Expand Down Expand Up @@ -774,23 +774,6 @@ class Gui:
cmd = None
arsenalGlobalVars = {}
savefile = config.savevarfile
# colors
BASIC_COLOR = 0 # output std
COL1_COLOR = 7
COL2_COLOR = 4 # gold
COL3_COLOR = 14 # purple light
COL4_COLOR = 5 # 26 # violet clair: 14 # 4 yellow # 6 purple # 7 cyan # 9 dark grey
COL5_COLOR = 5 # blue
COL1_COLOR_SELECT = 256 # output std invert
COL2_COLOR_SELECT = 256
COL3_COLOR_SELECT = 256
COL4_COLOR_SELECT = 256
CURSOR_COLOR_SELECT = 266 # background red
PROMPT_COLOR = 0
INFO_NAME_COLOR = 4 # 5
INFO_DESC_COLOR = 0
INFO_CMD_COLOR = 0
ARG_NAME_COLOR = 5

loaded_menu = False

Expand Down

0 comments on commit 20474b2

Please sign in to comment.