Stop using shell in subprocess calls (#6)
* restrict access to temp directory and files, and add optional --cache CLI arg to pass down to op * stop using shell=True when calling subprocess
This commit is contained in:
parent
3be11192a7
commit
63afed98d3
|
@ -23,16 +23,16 @@ LAST_ITEM_PATH = os.path.join(CACHE_DIR, "last_item")
|
||||||
LAST_ITEM_DURATION = timedelta(seconds=10)
|
LAST_ITEM_DURATION = timedelta(seconds=10)
|
||||||
|
|
||||||
OP_SUBDOMAIN = "my"
|
OP_SUBDOMAIN = "my"
|
||||||
CMD_PASSWORD_PROMPT = (
|
CMD_PASSWORD_PROMPT = [
|
||||||
"rofi -password -dmenu -p 'Vault Password' -l 0 -sidebar -width 20"
|
"rofi", "-password", "-dmenu", "-p", "Vault Password", "-l", "0", "-sidebar", "-width", "20"
|
||||||
)
|
]
|
||||||
CMD_ITEM_SELECT = "echo -e '{items}' | rofi -dmenu -p 'Select login'"
|
CMD_LIST_PROMPT = ["rofi", "-dmenu"]
|
||||||
CMD_LIST_PROMPT = "echo {items} | rofi -dmenu"
|
CMD_ITEM_SELECT = CMD_LIST_PROMPT + ["-p", "Select login"]
|
||||||
|
|
||||||
CMD_OP_LOGIN = "echo -n '{password}' | op signin {subdomain} --output=raw"
|
CMD_OP_LOGIN = ["op", "signin", "--output=raw"]
|
||||||
CMD_OP_LIST_ITEMS = "op list items --categories Login --session={session_id}"
|
CMD_OP_LIST_ITEMS = "op list items --categories Login --session {session_id}"
|
||||||
CMD_OP_GET_ITEM = "op get item {uuid} --session={session_id}"
|
CMD_OP_GET_ITEM = "op get item --session {session_id} {uuid}"
|
||||||
CMD_OP_GET_TOTP = "op get totp {uuid} --session={session_id}"
|
CMD_OP_GET_TOTP = "op get totp --session {session_id} {uuid}"
|
||||||
|
|
||||||
QUTE_FIFO = os.environ["QUTE_FIFO"]
|
QUTE_FIFO = os.environ["QUTE_FIFO"]
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class ExecuteError(Exception):
|
||||||
|
|
||||||
def execute_command(command):
|
def execute_command(command):
|
||||||
"""Executes a command, mainly used to launch commands for user input and the op cli"""
|
"""Executes a command, mainly used to launch commands for user input and the op cli"""
|
||||||
result = subprocess.run(command, shell=True, capture_output=True, encoding="utf-8")
|
result = subprocess.run(command, capture_output=True, encoding="utf-8")
|
||||||
|
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
logger.error(result.stderr)
|
logger.error(result.stderr)
|
||||||
|
@ -125,6 +125,14 @@ def execute_command(command):
|
||||||
return result.stdout.strip()
|
return result.stdout.strip()
|
||||||
|
|
||||||
|
|
||||||
|
def pipe_commands(cmd1, cmd2):
|
||||||
|
p1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE)
|
||||||
|
p2 = subprocess.Popen(cmd2, stdin=p1.stdout, stdout=subprocess.PIPE)
|
||||||
|
p1.stdout.close()
|
||||||
|
|
||||||
|
return p2.communicate()[0].decode("utf-8").strip()
|
||||||
|
|
||||||
|
|
||||||
def extract_host(url):
|
def extract_host(url):
|
||||||
"""Extracts the host from a given URL"""
|
"""Extracts the host from a given URL"""
|
||||||
_, host, *_ = urlsplit(url)
|
_, host, *_ = urlsplit(url)
|
||||||
|
@ -143,9 +151,9 @@ class OnePass:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
session_id = execute_command(
|
session_id = pipe_commands(
|
||||||
CMD_OP_LOGIN.format(password=password, subdomain=OP_SUBDOMAIN)
|
["echo", "-n", password],
|
||||||
)
|
CMD_OP_LOGIN + [OP_SUBDOMAIN])
|
||||||
except ExecuteError:
|
except ExecuteError:
|
||||||
Qute.message_error("Login error")
|
Qute.message_error("Login error")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
@ -177,7 +185,7 @@ class OnePass:
|
||||||
@classmethod
|
@classmethod
|
||||||
def list_items(cls):
|
def list_items(cls):
|
||||||
session_id = cls.get_session()
|
session_id = cls.get_session()
|
||||||
result = execute_command(CMD_OP_LIST_ITEMS.format(session_id=session_id))
|
result = execute_command(CMD_OP_LIST_ITEMS.format(session_id=session_id).split())
|
||||||
parsed = json.loads(result)
|
parsed = json.loads(result)
|
||||||
return parsed
|
return parsed
|
||||||
|
|
||||||
|
@ -186,7 +194,7 @@ class OnePass:
|
||||||
session_id = cls.get_session()
|
session_id = cls.get_session()
|
||||||
try:
|
try:
|
||||||
result = execute_command(
|
result = execute_command(
|
||||||
CMD_OP_GET_ITEM.format(uuid=uuid, session_id=session_id)
|
CMD_OP_GET_ITEM.format(uuid=uuid, session_id=session_id).split()
|
||||||
)
|
)
|
||||||
except ExecuteError:
|
except ExecuteError:
|
||||||
logger.error("Error retrieving credential", exc_info=True)
|
logger.error("Error retrieving credential", exc_info=True)
|
||||||
|
@ -215,8 +223,8 @@ class OnePass:
|
||||||
raise cls.NoItemsFoundError(f"No items found for host {host}")
|
raise cls.NoItemsFoundError(f"No items found for host {host}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
credential = execute_command(
|
credential = pipe_commands(
|
||||||
CMD_ITEM_SELECT.format(items="\n".join(mapping.keys()))
|
["echo", "\n".join(mapping.keys())], CMD_ITEM_SELECT
|
||||||
)
|
)
|
||||||
except ExecuteError:
|
except ExecuteError:
|
||||||
pass
|
pass
|
||||||
|
@ -251,7 +259,7 @@ class OnePass:
|
||||||
session_id = cls.get_session()
|
session_id = cls.get_session()
|
||||||
try:
|
try:
|
||||||
return execute_command(
|
return execute_command(
|
||||||
CMD_OP_GET_TOTP.format(uuid=uuid, session_id=session_id)
|
CMD_OP_GET_TOTP.format(uuid=uuid, session_id=session_id).split()
|
||||||
)
|
)
|
||||||
except ExecuteError:
|
except ExecuteError:
|
||||||
logger.error("Error retrieving TOTP", exc_info=True)
|
logger.error("Error retrieving TOTP", exc_info=True)
|
||||||
|
|
Loading…
Reference in New Issue