@@ -454,10 +454,14 @@ async def connect_agent(self) -> None:
454
454
455
455
dirs = subprocess .check_output (
456
456
['gpgconf' , * self .homedir_opts (), '--list-dirs' , '-o/dev/stdout' ])
457
- if self .allow_keygen :
458
- socket_field = b'agent-socket:'
459
- else :
460
- socket_field = b'agent-extra-socket:'
457
+ # Do not use the restricted socket.
458
+ # Sequoia Chameleon is unable to list secret keys or decrypt messages,
459
+ # and gpg prints "gpg: problem with fast path key listing: Forbidden - ignored",
460
+ # which causes Mutt to require the user to press "Enter" again before sending
461
+ # a message.
462
+ # The filtering done by split-gpg2 is far stronger than anything the agent does
463
+ # internally.
464
+ socket_field = b'agent-socket:'
461
465
# search for agent-socket:/run/user/1000/gnupg/S.gpg-agent
462
466
agent_socket_path = [d .split (b':' , 1 )[1 ] for d in dirs .splitlines ()
463
467
if d .startswith (socket_field )][0 ]
@@ -641,14 +645,24 @@ def fake_respond(self, response: bytes) -> None:
641
645
642
646
@staticmethod
643
647
def verify_keygrip_arguments (min_count : int , max_count : int ,
644
- untrusted_args : Optional [bytes ]) -> bytes :
648
+ untrusted_args : Optional [bytes ],
649
+ allow_list : bool ) -> bytes :
645
650
if untrusted_args is None :
646
651
raise Filtered
647
- args_regex = re .compile (rb'\A[0-9A-F]{40}( [0-9A-F]{40}){%d,%d}\Z' %
648
- (min_count - 1 , max_count - 1 ))
652
+ if allow_list and untrusted_args .startswith (b'--list' ):
653
+ if untrusted_args == b'--list' :
654
+ pass
655
+ elif untrusted_args [6 ] == 61 : # ASCII '='
656
+ # 1000 is the default value used by gpg2
657
+ sanitize_int (untrusted_args [len (b'--list=' ):], 1 , 1000 )
658
+ else :
659
+ raise Filtered
660
+ else :
661
+ args_regex = re .compile (rb'\A[0-9A-F]{40}( [0-9A-F]{40}){%d,%d}\Z' %
662
+ (min_count - 1 , max_count - 1 ))
649
663
650
- if args_regex .match (untrusted_args ) is None :
651
- raise Filtered
664
+ if args_regex .match (untrusted_args ) is None :
665
+ raise Filtered
652
666
return untrusted_args
653
667
654
668
def sanitize_key_desc (self , untrusted_args : bytes ) -> bytes :
@@ -731,21 +745,11 @@ async def command_HAVEKEY(self, untrusted_args: Optional[bytes]) -> None:
731
745
if untrusted_args is None :
732
746
raise Filtered
733
747
# upper keygrip limit is arbitary
734
- if untrusted_args .startswith (b'--list' ):
735
- if b'=' in untrusted_args :
736
- # 1000 is the default value used by gpg2
737
- limit = sanitize_int (untrusted_args [len (b'--list=' ):], 1 , 1000 )
738
- args = b'--list=%d' % limit
739
- else :
740
- if untrusted_args != b'--list' :
741
- raise Filtered
742
- args = b'--list'
743
- else :
744
- args = self .verify_keygrip_arguments (1 , 200 , untrusted_args )
748
+ args = self .verify_keygrip_arguments (1 , 200 , untrusted_args , True )
745
749
await self .send_agent_command (b'HAVEKEY' , args )
746
750
747
751
async def command_KEYINFO (self , untrusted_args : Optional [bytes ]) -> None :
748
- args = self .verify_keygrip_arguments (1 , 1 , untrusted_args )
752
+ args = self .verify_keygrip_arguments (1 , 1 , untrusted_args , True )
749
753
await self .send_agent_command (b'KEYINFO' , args )
750
754
751
755
async def command_GENKEY (self , untrusted_args : Optional [bytes ]) -> None :
@@ -785,12 +789,12 @@ async def command_GENKEY(self, untrusted_args: Optional[bytes]) -> None:
785
789
await self .send_agent_command (b'GENKEY' , b' ' .join (args ))
786
790
787
791
async def command_SIGKEY (self , untrusted_args : Optional [bytes ]) -> None :
788
- args = self .verify_keygrip_arguments (1 , 1 , untrusted_args )
792
+ args = self .verify_keygrip_arguments (1 , 1 , untrusted_args , False )
789
793
await self .send_agent_command (b'SIGKEY' , args )
790
794
await self .setkeydesc (args )
791
795
792
796
async def command_SETKEY (self , untrusted_args : Optional [bytes ]) -> None :
793
- args = self .verify_keygrip_arguments (1 , 1 , untrusted_args )
797
+ args = self .verify_keygrip_arguments (1 , 1 , untrusted_args , False )
794
798
await self .send_agent_command (b'SETKEY' , args )
795
799
await self .setkeydesc (args )
796
800
@@ -996,7 +1000,7 @@ async def command_READKEY(self, untrusted_args: Optional[bytes]) -> None:
996
1000
raise Filtered
997
1001
if untrusted_args .startswith (b'-- ' ):
998
1002
untrusted_args = untrusted_args [3 :]
999
- args = self .verify_keygrip_arguments (1 , 1 , untrusted_args )
1003
+ args = self .verify_keygrip_arguments (1 , 1 , untrusted_args , False )
1000
1004
1001
1005
await self .send_agent_command (b'READKEY' , b'-- ' + args )
1002
1006
0 commit comments