docs and examples: python bindings
* Woumd up the "what's new" section. * Added an example for sending a key to the keyservers via hkp4py. * Updated the export key code to use a more complete check for the $GNUPGHOME location. * Expanded on the installation and reinstallation troubleshooting section. Tested-by: Ben McGinnes <ben@adversary.org> Signed-off-by: Ben McGinnes <ben@adversary.org>
This commit is contained in:
parent
e9da4d9710
commit
62e4e2cb5e
@ -64,6 +64,10 @@ GPGME Python bindings installation
|
|||||||
* Installation::
|
* Installation::
|
||||||
* Known Issues::
|
* Known Issues::
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
|
||||||
|
* Recommended Additions::
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
|
||||||
* Installing GPGME::
|
* Installing GPGME::
|
||||||
@ -71,6 +75,7 @@ Installation
|
|||||||
Known Issues
|
Known Issues
|
||||||
|
|
||||||
* Breaking Builds::
|
* Breaking Builds::
|
||||||
|
* Reinstalling Responsibly::
|
||||||
* Multiple installations::
|
* Multiple installations::
|
||||||
* Won't Work With Windows::
|
* Won't Work With Windows::
|
||||||
* CFFI is the Best™ and GPGME should use it instead of SWIG::
|
* CFFI is the Best™ and GPGME should use it instead of SWIG::
|
||||||
@ -101,6 +106,7 @@ Exporting keys
|
|||||||
|
|
||||||
* Exporting public keys::
|
* Exporting public keys::
|
||||||
* Exporting secret keys::
|
* Exporting secret keys::
|
||||||
|
* Sending public keys to the SKS Keyservers::
|
||||||
|
|
||||||
Basic Functions
|
Basic Functions
|
||||||
|
|
||||||
@ -445,7 +451,8 @@ The GPGME Python bindings only have three requirements:
|
|||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
A suitable version of Python 2 or Python 3. With Python 2 that
|
A suitable version of Python 2 or Python 3. With Python 2 that
|
||||||
means Python 2.7 and with Python 3 that means Python 3.4 or higher.
|
means CPython 2.7 and with Python 3 that means CPython 3.4 or
|
||||||
|
higher.
|
||||||
@item
|
@item
|
||||||
@uref{https://www.swig.org, SWIG}.
|
@uref{https://www.swig.org, SWIG}.
|
||||||
@item
|
@item
|
||||||
@ -453,6 +460,33 @@ GPGME itself. Which also means that all of GPGME's dependencies
|
|||||||
must be installed too.
|
must be installed too.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Recommended Additions::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Recommended Additions
|
||||||
|
@subsection Recommended Additions
|
||||||
|
|
||||||
|
Though none of the following are absolute requirements, they are all
|
||||||
|
recommended for use with the Python bindings. In some cases these
|
||||||
|
recommendations refer to which version(s) of CPython to use the
|
||||||
|
bindings with, while others refer to third party modules which provide
|
||||||
|
a significant advantage in some way.
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
If possible, use Python 3 instead of 2.
|
||||||
|
@item
|
||||||
|
Favour a more recent version of Python since even 3.4 is due to
|
||||||
|
reach EOL soon. In production systems and services, Python 3.6
|
||||||
|
should be robust enough to be relied on.
|
||||||
|
@item
|
||||||
|
If possible add the following Python modules which are not part of
|
||||||
|
the standard library: @uref{http://docs.python-requests.org/en/latest/index.html, Requests}, @uref{http://cython.org/, Cython} and @uref{https://github.com/Selfnet/hkp4py, hkp4py}. Chances are
|
||||||
|
quite high that at least the first one and maybe two of those will
|
||||||
|
already be installed.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
@node Installation
|
@node Installation
|
||||||
@section Installation
|
@section Installation
|
||||||
|
|
||||||
@ -495,6 +529,7 @@ they be encountered.
|
|||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Breaking Builds::
|
* Breaking Builds::
|
||||||
|
* Reinstalling Responsibly::
|
||||||
* Multiple installations::
|
* Multiple installations::
|
||||||
* Won't Work With Windows::
|
* Won't Work With Windows::
|
||||||
* CFFI is the Best™ and GPGME should use it instead of SWIG::
|
* CFFI is the Best™ and GPGME should use it instead of SWIG::
|
||||||
@ -559,10 +594,34 @@ If Python is set to precede one of the other languages then it is
|
|||||||
possible that the errors described here may interrupt the build
|
possible that the errors described here may interrupt the build
|
||||||
process before generating bindings for those other languages. In
|
process before generating bindings for those other languages. In
|
||||||
these cases it may be preferable to configure all preferred language
|
these cases it may be preferable to configure all preferred language
|
||||||
howto-export-public-keybindings separately with alternative @samp{configure} steps for GPGME using
|
bindings separately with alternative @samp{configure} steps for GPGME using
|
||||||
the @samp{--enable-languages=$LANGUAGE} option.
|
the @samp{--enable-languages=$LANGUAGE} option.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
|
@node Reinstalling Responsibly
|
||||||
|
@subsection Reinstalling Responsibly
|
||||||
|
|
||||||
|
Regardless of whether you're installing for one version of Python or
|
||||||
|
several, there will come a point where reinstallation is required.
|
||||||
|
With most Python module installations, the installed files go into the
|
||||||
|
relevant site-packages directory and are then forgotten about. Then
|
||||||
|
the module is upgraded, the new files are copied over the old and
|
||||||
|
that's the end of the matter.
|
||||||
|
|
||||||
|
While the same is true of these bindings, there have been intermittent
|
||||||
|
issues observed on some platforms which have benefited significantly
|
||||||
|
from removing all the previous installations of the bindings before
|
||||||
|
installing the updated versions.
|
||||||
|
|
||||||
|
Removing the previous version(s) is simply a matter of changing to the
|
||||||
|
relevant @samp{site-packages} directory for the version of Python in
|
||||||
|
question and removing the @samp{gpg/} directory and any accompanying
|
||||||
|
egg-info files for that module.
|
||||||
|
|
||||||
|
In most cases this will require root or administration privileges on
|
||||||
|
the system, but the same is true of installing the module in the first
|
||||||
|
place.
|
||||||
|
|
||||||
@node Multiple installations
|
@node Multiple installations
|
||||||
@subsection Multiple installations
|
@subsection Multiple installations
|
||||||
|
|
||||||
@ -1427,6 +1486,7 @@ third is for exporting secret keys.
|
|||||||
@menu
|
@menu
|
||||||
* Exporting public keys::
|
* Exporting public keys::
|
||||||
* Exporting secret keys::
|
* Exporting secret keys::
|
||||||
|
* Sending public keys to the SKS Keyservers::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Exporting public keys
|
@node Exporting public keys
|
||||||
@ -1586,12 +1646,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
@ -1656,12 +1730,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
@ -1712,6 +1800,70 @@ else:
|
|||||||
pass
|
pass
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@node Sending public keys to the SKS Keyservers
|
||||||
|
@subsection Sending public keys to the SKS Keyservers
|
||||||
|
|
||||||
|
As with the previous section on importing keys, the @samp{hkp4py} module
|
||||||
|
adds another option with exporting keys in order to send them to the
|
||||||
|
public keyservers.
|
||||||
|
|
||||||
|
The following example demonstrates how this may be done.
|
||||||
|
|
||||||
|
@example
|
||||||
|
import gpg
|
||||||
|
import hkp4py
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print("""
|
||||||
|
This script sends one or more public keys to the SKS keyservers and is
|
||||||
|
essentially a slight variation on the export-key.py script.
|
||||||
|
""")
|
||||||
|
|
||||||
|
c = gpg.Context(armor=True)
|
||||||
|
server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
|
||||||
|
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
logrus = " ".join(sys.argv[1:])
|
||||||
|
elif len(sys.argv) == 2:
|
||||||
|
logrus = sys.argv[1]
|
||||||
|
else:
|
||||||
|
logrus = input("Enter the UID matching the key(s) to send: ")
|
||||||
|
|
||||||
|
if len(logrus) > 0:
|
||||||
|
try:
|
||||||
|
export_result = c.key_export(pattern=logrus)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
export_result = None
|
||||||
|
else:
|
||||||
|
export_result = c.key_export(pattern=None)
|
||||||
|
|
||||||
|
if export_result is not None:
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
send_result = server.add(export_result)
|
||||||
|
except:
|
||||||
|
send_result = server.add(export_result.decode())
|
||||||
|
if send_result is not None:
|
||||||
|
print(send_result)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
@end example
|
||||||
|
|
||||||
|
An expanded version of this script with additional functions for
|
||||||
|
specifying an alternative homedir location is in the examples
|
||||||
|
directory as @samp{send-key-to-keyserver.py}.
|
||||||
|
|
||||||
|
The @samp{hkp4py} module appears to handle both string and byte literal text
|
||||||
|
data equally well, but the GPGME bindings deal primarily with byte
|
||||||
|
literal data only and so this script sends in that format first, then
|
||||||
|
tries the string literal form.
|
||||||
|
|
||||||
@node Basic Functions
|
@node Basic Functions
|
||||||
@chapter Basic Functions
|
@chapter Basic Functions
|
||||||
|
|
||||||
|
@ -293,12 +293,34 @@ section for further details.
|
|||||||
The GPGME Python bindings only have three requirements:
|
The GPGME Python bindings only have three requirements:
|
||||||
|
|
||||||
1. A suitable version of Python 2 or Python 3. With Python 2 that
|
1. A suitable version of Python 2 or Python 3. With Python 2 that
|
||||||
means Python 2.7 and with Python 3 that means Python 3.4 or higher.
|
means CPython 2.7 and with Python 3 that means CPython 3.4 or
|
||||||
|
higher.
|
||||||
2. [[https://www.swig.org][SWIG]].
|
2. [[https://www.swig.org][SWIG]].
|
||||||
3. GPGME itself. Which also means that all of GPGME's dependencies
|
3. GPGME itself. Which also means that all of GPGME's dependencies
|
||||||
must be installed too.
|
must be installed too.
|
||||||
|
|
||||||
|
|
||||||
|
*** Recommended Additions
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: gpgme-python-recommendations
|
||||||
|
:END:
|
||||||
|
|
||||||
|
Though none of the following are absolute requirements, they are all
|
||||||
|
recommended for use with the Python bindings. In some cases these
|
||||||
|
recommendations refer to which version(s) of CPython to use the
|
||||||
|
bindings with, while others refer to third party modules which provide
|
||||||
|
a significant advantage in some way.
|
||||||
|
|
||||||
|
1. If possible, use Python 3 instead of 2.
|
||||||
|
2. Favour a more recent version of Python since even 3.4 is due to
|
||||||
|
reach EOL soon. In production systems and services, Python 3.6
|
||||||
|
should be robust enough to be relied on.
|
||||||
|
3. If possible add the following Python modules which are not part of
|
||||||
|
the standard library: [[http://docs.python-requests.org/en/latest/index.html][Requests]], [[http://cython.org/][Cython]] and [[https://github.com/Selfnet/hkp4py][hkp4py]]. Chances are
|
||||||
|
quite high that at least the first one and maybe two of those will
|
||||||
|
already be installed.
|
||||||
|
|
||||||
|
|
||||||
** Installation
|
** Installation
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: installation
|
:CUSTOM_ID: installation
|
||||||
@ -398,10 +420,37 @@ If Python is set to precede one of the other languages then it is
|
|||||||
possible that the errors described here may interrupt the build
|
possible that the errors described here may interrupt the build
|
||||||
process before generating bindings for those other languages. In
|
process before generating bindings for those other languages. In
|
||||||
these cases it may be preferable to configure all preferred language
|
these cases it may be preferable to configure all preferred language
|
||||||
howto-export-public-keybindings separately with alternative =configure= steps for GPGME using
|
bindings separately with alternative =configure= steps for GPGME using
|
||||||
the =--enable-languages=$LANGUAGE= option.
|
the =--enable-languages=$LANGUAGE= option.
|
||||||
|
|
||||||
|
|
||||||
|
*** Reinstalling Responsibly
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: snafu-lessons-for-the-lazy
|
||||||
|
:END:
|
||||||
|
|
||||||
|
Regardless of whether you're installing for one version of Python or
|
||||||
|
several, there will come a point where reinstallation is required.
|
||||||
|
With most Python module installations, the installed files go into the
|
||||||
|
relevant site-packages directory and are then forgotten about. Then
|
||||||
|
the module is upgraded, the new files are copied over the old and
|
||||||
|
that's the end of the matter.
|
||||||
|
|
||||||
|
While the same is true of these bindings, there have been intermittent
|
||||||
|
issues observed on some platforms which have benefited significantly
|
||||||
|
from removing all the previous installations of the bindings before
|
||||||
|
installing the updated versions.
|
||||||
|
|
||||||
|
Removing the previous version(s) is simply a matter of changing to the
|
||||||
|
relevant =site-packages= directory for the version of Python in
|
||||||
|
question and removing the =gpg/= directory and any accompanying
|
||||||
|
egg-info files for that module.
|
||||||
|
|
||||||
|
In most cases this will require root or administration privileges on
|
||||||
|
the system, but the same is true of installing the module in the first
|
||||||
|
place.
|
||||||
|
|
||||||
|
|
||||||
*** Multiple installations
|
*** Multiple installations
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: snafu-the-full-monty
|
:CUSTOM_ID: snafu-the-full-monty
|
||||||
@ -1446,12 +1495,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
@ -1516,12 +1579,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
@ -1573,6 +1650,73 @@ else:
|
|||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
|
*** Sending public keys to the SKS Keyservers
|
||||||
|
:PROPERTIES:
|
||||||
|
:CUSTOM_ID: howto-send-public-key
|
||||||
|
:END:
|
||||||
|
|
||||||
|
As with the previous section on importing keys, the =hkp4py= module
|
||||||
|
adds another option with exporting keys in order to send them to the
|
||||||
|
public keyservers.
|
||||||
|
|
||||||
|
The following example demonstrates how this may be done.
|
||||||
|
|
||||||
|
#+BEGIN_SRC python -i
|
||||||
|
import gpg
|
||||||
|
import hkp4py
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
print("""
|
||||||
|
This script sends one or more public keys to the SKS keyservers and is
|
||||||
|
essentially a slight variation on the export-key.py script.
|
||||||
|
""")
|
||||||
|
|
||||||
|
c = gpg.Context(armor=True)
|
||||||
|
server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
|
||||||
|
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
logrus = " ".join(sys.argv[1:])
|
||||||
|
elif len(sys.argv) == 2:
|
||||||
|
logrus = sys.argv[1]
|
||||||
|
else:
|
||||||
|
logrus = input("Enter the UID matching the key(s) to send: ")
|
||||||
|
|
||||||
|
if len(logrus) > 0:
|
||||||
|
try:
|
||||||
|
export_result = c.key_export(pattern=logrus)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
export_result = None
|
||||||
|
else:
|
||||||
|
export_result = c.key_export(pattern=None)
|
||||||
|
|
||||||
|
if export_result is not None:
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
send_result = server.add(export_result)
|
||||||
|
except:
|
||||||
|
send_result = server.add(export_result.decode())
|
||||||
|
if send_result is not None:
|
||||||
|
print(send_result)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
An expanded version of this script with additional functions for
|
||||||
|
specifying an alternative homedir location is in the examples
|
||||||
|
directory as =send-key-to-keyserver.py=.
|
||||||
|
|
||||||
|
The =hkp4py= module appears to handle both string and byte literal text
|
||||||
|
data equally well, but the GPGME bindings deal primarily with byte
|
||||||
|
literal data only and so this script sends in that format first, then
|
||||||
|
tries the string literal form.
|
||||||
|
|
||||||
|
|
||||||
* Basic Functions
|
* Basic Functions
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:CUSTOM_ID: howto-the-basics
|
:CUSTOM_ID: howto-the-basics
|
||||||
|
@ -51,12 +51,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the key(s) to export: ")
|
logrus = input("Enter the UID matching the key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
@ -51,12 +51,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the key(s) to export: ")
|
logrus = input("Enter the UID matching the key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
@ -54,12 +54,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
@ -63,12 +63,26 @@ else:
|
|||||||
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
logrus = input("Enter the UID matching the secret key(s) to export: ")
|
||||||
homedir = input("Enter the GPG configuration directory path (optional): ")
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
if homedir.startswith("~"):
|
if len(homedir) == 0:
|
||||||
if os.path.exists(os.path.expanduser(homedir)) is True:
|
homedir = None
|
||||||
c.home_dir = os.path.expanduser(homedir)
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
elif os.path.exists(homedir) is True:
|
|
||||||
|
if homedir is not None:
|
||||||
c.home_dir = homedir
|
c.home_dir = homedir
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
98
lang/python/examples/howto/send-key-to-keyserver.py
Executable file
98
lang/python/examples/howto/send-key-to-keyserver.py
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, unicode_literals
|
||||||
|
|
||||||
|
import gpg
|
||||||
|
import hkp4py
|
||||||
|
import os.path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Copyright (C) 2018 Ben McGinnes <ben@gnupg.org>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 2 of the License, or (at your option) any later
|
||||||
|
# version.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 2.1 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU
|
||||||
|
# Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License and the GNU
|
||||||
|
# Lesser General Public along with this program; if not, see
|
||||||
|
# <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
print("""
|
||||||
|
This script sends one or more public keys to the SKS keyservers and is
|
||||||
|
essentially a slight variation on the export-key.py script.
|
||||||
|
|
||||||
|
The default is to send all keys if there is no pattern or search term.
|
||||||
|
""")
|
||||||
|
|
||||||
|
c = gpg.Context(armor=True)
|
||||||
|
server = hkp4py.KeyServer("hkps://hkps.pool.sks-keyservers.net")
|
||||||
|
|
||||||
|
if len(sys.argv) >= 3:
|
||||||
|
logrus = sys.argv[1]
|
||||||
|
homedir = sys.argv[2]
|
||||||
|
elif len(sys.argv) == 2:
|
||||||
|
logrus = sys.argv[1]
|
||||||
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
else:
|
||||||
|
logrus = input("Enter the UID matching the key(s) to export: ")
|
||||||
|
homedir = input("Enter the GPG configuration directory path (optional): ")
|
||||||
|
|
||||||
|
if len(homedir) == 0:
|
||||||
|
homedir = None
|
||||||
|
elif homedir.startswith("~"):
|
||||||
|
userdir = os.path.expanduser(homedir)
|
||||||
|
if os.path.exists(userdir) is True:
|
||||||
|
homedir = os.path.realpath(userdir)
|
||||||
|
else:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
homedir = os.path.realpath(homedir)
|
||||||
|
|
||||||
|
if os.path.exists(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
if os.path.isdir(homedir) is False:
|
||||||
|
homedir = None
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if homedir is not None:
|
||||||
|
c.home_dir = homedir
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if len(logrus) > 0:
|
||||||
|
try:
|
||||||
|
export_result = c.key_export(pattern=logrus)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
export_result = None
|
||||||
|
else:
|
||||||
|
export_result = c.key_export(pattern=None)
|
||||||
|
|
||||||
|
if export_result is not None:
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
send_result = server.add(export_result)
|
||||||
|
except:
|
||||||
|
send_result = server.add(export_result.decode())
|
||||||
|
if send_result is not None:
|
||||||
|
print(send_result)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
else:
|
||||||
|
pass
|
Loading…
Reference in New Issue
Block a user