Skip to content

Commit ebf46f9

Browse files
committed
Allow "KEYINFO --list"
Currently, this command is blocked. GnuPG detects that the agent connection is restricted and doesn't try to use it, while Sequoia Chameleon does not implement the fallback and is unable to list secret keys or decrypt messages. Furthermore, gpg prints "gpg: problem with fast path key listing: Forbidden - ignored", which Mutt interprets as a prompt the user must respond to. This causes the user to need to press enter twice to send a signed email. Fix these problems by allowing this request. The request does not work over a restricted connection, so an unrestricted connection must be used. However, the filtering done by split-gpg2 is far stronger than the access checks in gpg-agent so there is no loss of security. Fixes: QubesOS/qubes-issues#9529
1 parent cff7f8e commit ebf46f9

1 file changed

Lines changed: 16 additions & 17 deletions

File tree

splitgpg2/__init__.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ async def connect_agent(self) -> None:
459459
if self.allow_keygen:
460460
socket_field = b'agent-socket:'
461461
else:
462-
socket_field = b'agent-extra-socket:'
462+
socket_field = b'agent-extra-socket'
463463
# search for agent-socket:/run/user/1000/gnupg/S.gpg-agent
464464
agent_socket_path = [d.split(b':', 1)[1] for d in dirs.splitlines()
465465
if d.startswith(socket_field)][0]
@@ -643,9 +643,18 @@ def fake_respond(self, response: bytes) -> None:
643643

644644
@staticmethod
645645
def verify_keygrip_arguments(min_count: int, max_count: int,
646-
untrusted_args: Optional[bytes]) -> bytes:
646+
untrusted_args: Optional[bytes],
647+
allow_list: bool) -> bytes:
647648
if untrusted_args is None:
648649
raise Filtered
650+
if allow_list and untrusted_args.startswith(b'--list'):
651+
if untrusted_args == b'--list':
652+
return b'--list'
653+
if untrusted_args[6] == 61: # ASCII '='
654+
# 1000 is the default value used by gpg2
655+
return b'--list=%d' % sanitize_int(untrusted_args[7:], 1, 1000)
656+
raise Filtered
657+
untrusted_args_list: List[bytes] = untrusted_args.split(b' ')
649658
if not (min_count <= len(untrusted_args_list) <= max_count):
650659
raise Filtered
651660
for untrusted_arg in untrusted_args_list:
@@ -728,21 +737,11 @@ async def command_HAVEKEY(self, untrusted_args: Optional[bytes]) -> None:
728737
if untrusted_args is None:
729738
raise Filtered
730739
# upper keygrip limit is arbitary
731-
if untrusted_args.startswith(b'--list'):
732-
if b'=' in untrusted_args:
733-
# 1000 is the default value used by gpg2
734-
limit = sanitize_int(untrusted_args[len(b'--list='):], 1, 1000)
735-
args = b'--list=%d' % limit
736-
else:
737-
if untrusted_args != b'--list':
738-
raise Filtered
739-
args = b'--list'
740-
else:
741-
args = self.verify_keygrip_arguments(1, 200, untrusted_args)
740+
args = self.verify_keygrip_arguments(1, 200, untrusted_args, True)
742741
await self.send_agent_command(b'HAVEKEY', args)
743742

744743
async def command_KEYINFO(self, untrusted_args: Optional[bytes]) -> None:
745-
args = self.verify_keygrip_arguments(1, 1, untrusted_args)
744+
args = self.verify_keygrip_arguments(1, 1, untrusted_args, True)
746745
await self.send_agent_command(b'KEYINFO', args)
747746

748747
async def command_GENKEY(self, untrusted_args: Optional[bytes]) -> None:
@@ -782,12 +781,12 @@ async def command_GENKEY(self, untrusted_args: Optional[bytes]) -> None:
782781
await self.send_agent_command(b'GENKEY', b' '.join(args))
783782

784783
async def command_SIGKEY(self, untrusted_args: Optional[bytes]) -> None:
785-
args = self.verify_keygrip_arguments(1, 1, untrusted_args)
784+
args = self.verify_keygrip_arguments(1, 1, untrusted_args, False)
786785
await self.send_agent_command(b'SIGKEY', args)
787786
await self.setkeydesc(args)
788787

789788
async def command_SETKEY(self, untrusted_args: Optional[bytes]) -> None:
790-
args = self.verify_keygrip_arguments(1, 1, untrusted_args)
789+
args = self.verify_keygrip_arguments(1, 1, untrusted_args, False)
791790
await self.send_agent_command(b'SETKEY', args)
792791
await self.setkeydesc(args)
793792

@@ -992,7 +991,7 @@ async def command_READKEY(self, untrusted_args: Optional[bytes]) -> None:
992991
raise Filtered
993992
if untrusted_args.startswith(b'-- '):
994993
untrusted_args = untrusted_args[3:]
995-
args = self.verify_keygrip_arguments(1, 1, untrusted_args)
994+
args = self.verify_keygrip_arguments(1, 1, untrusted_args, False)
996995

997996
await self.send_agent_command(b'READKEY', b'-- ' + args)
998997

0 commit comments

Comments
 (0)