gnupghome don't support non-ascii paths

Issue #41 resolved
Kévin Bernard-Allies
created an issue

Under Python 2.7, it's not possible to use a path containing non-ascii characters in the gnupghome path.

GPG(gnupghome=u'./Kévin') will raise an UnicodeEncodeError.

Although calling GPG(gnupghome=u'./Kévin'.encode(sys.getfilesystemencoding())) seems to work fine, all subsequent calls to export_keys() raise an UnicodeDecodeError.

I've not tested all methods, but there is probably others methods who have the same problem.

Note: my filesystem encoding is latin1.

Comments (8)

  1. Kévin Bernard-Allies reporter

    I've a french installation of Windows 10, and I'v tested with Windows 7 (also french) with the same results.

    Here is the code I've executed:

    # -*- coding: utf-8 -*-
    
    import locale
    import sys
    from gnupg import GPG
    
    print('Default encoding: %s' % sys.getdefaultencoding())
    print('Filesystem encoding: %s' % sys.getfilesystemencoding())
    print('Preferred encoding: %s' % locale.getpreferredencoding())
    
    gpg = GPG(gnupghome=u'./Kévin')
    

    stdout:

    Default encoding: ascii
    Filesystem encoding: mbcs
    Preferred encoding: cp1252
    Traceback (most recent call last):
      File "gpg_enc.py", line 11, in <module>
        gpg = GPG(gnupghome=u'./Kévin')
      File "C:\Python27\lib\site-packages\gnupg.py", line 680, in __init__
        p = self._open_subprocess(["--version"])
      File "C:\Python27\lib\site-packages\gnupg.py", line 726, in _open_subprocess
        return Popen(cmd, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE)
      File "C:\Python27\lib\subprocess.py", line 710, in __init__
        errread, errwrite)
      File "C:\Python27\lib\subprocess.py", line 958, in _execute_child
        startupinfo)
    UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 41: ordinal not in range(128)
    

    Using a bytes instance for gnupghome, there is no exception raised, but the folder created on the disk is "Kévin".

    After that, I've tried to use sys.getfilesystemencoding():

    # -*- coding: utf-8 -*-
    
    import sys
    from gnupg import GPG
    
    gpg = GPG(gnupghome=u'./Kévin'.encode(sys.getfilesystemencoding()))
    
    input = gpg.gen_key_input()
    result = gpg.gen_key(input)
    
    print('Key generated: %s' % result)
    gpg.export_keys(result.fingerprint)
    

    Stdout:

    Key generated: 3BABE08E5D367074CD7EF9102722B786AD0AF820
    Traceback (most recent call last):
      File "gpg_enc.py", line 12, in <module>
        gpg.export_keys(result.fingerprint)
      File "C:\Python27\lib\site-packages\gnupg.py", line 1049, in export_keys
        p = self._open_subprocess(args)
      File "C:\Python27\lib\site-packages\gnupg.py", line 726, in _open_subprocess
        return Popen(cmd, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE)
      File "C:\Python27\lib\subprocess.py", line 710, in __init__
        errread, errwrite)
      File "C:\Python27\lib\subprocess.py", line 913, in _execute_child
        args = list2cmdline(args)
      File "C:\Python27\lib\subprocess.py", line 644, in list2cmdline
        return ''.join(result)
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)
    

    With Python 3.4, everything works perfect.

  2. Ian Denhardt

    I poked around a bit, found this: http://stackoverflow.com/questions/9992381/python-popen-failing-to-use-proper-encoding-in-windows-powershell

    ...which I'm pretty sure is related. From the stack trace it's pretty clear it's trying to encode the command (which will include the filename) as ascii, which isn't going to work. Can you try doing this after first running:

     sys.setdefaultencoding(encoding)
    

    with encoding set to each of:

    "latin-1"
    "utf-8"
    "mbcs"
    "cp1252"
    

    and get back to us with the results? Thanks.

    and yeah, better support for unicode is far and away the most important thing that python 3 did :/...

  3. Vinay Sajip repo owner

    There is a relevant Python issue - "subprocess.call fails with unicode strings in command line". This was last updated in 2010 and no fix for 2.x is coming (as it's considered a feature request). The appropriate solution for this issue appears to be to encode any Unicode user-provided parameters using the file system encoding on 2.x only.

  4. Kévin Bernard-Allies reporter

    OK, I've tested with the 4 encodings. It seems to works fine with "latin-1", "mbcs" and "cp1252". With "utf-8", the GPG initialization works, but the key generation fails, it can't find the GPG folder due to bad encoding.

    stderr:

    gpg: keyblock resource `./Kévin\secring.gpg': file open error
    gpg: keyblock resource `./Kévin\pubring.gpg': file open error
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen X 100 100
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen . 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen + 0 0
    [GNUPG:] PROGRESS primegen X 100 100
    [GNUPG:] GOOD_PASSPHRASE
    gpg: no writable public keyring found: eof
    gpg: key generation failed: eof
    [GNUPG:] KEY_NOT_CREATED 
    gpg: can't create `./Kévin\random_seed': No such file or directory
    

    let me known if you need more informations.

  5. Log in to comment