Apache/2.4.7 (Ubuntu) Linux sman1baleendah 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 uid=33(www-data) gid=33(www-data) groups=33(www-data) safemode : OFF MySQL: ON | Perl: ON | cURL: OFF | WGet: ON > / usr / lib / python2.7 / dist-packages / apt / | server ip : 104.21.89.46 your ip : 172.69.6.238 H O M E |
Filename | /usr/lib/python2.7/dist-packages/apt/auth.py |
Size | 9.02 kb |
Permission | rw-r--r-- |
Owner | root : root |
Create time | 27-Apr-2025 09:53 |
Last modified | 02-Apr-2014 06:37 |
Last accessed | 06-Jul-2025 10:30 |
Actions | edit | rename | delete | download (gzip) |
View | text | code | image |
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# auth - authentication key management
#
# Copyright (c) 2004 Canonical
# Copyright (c) 2012 Sebastian Heinlein
#
# Author: Michael Vogt <[email protected]>
# Sebastian Heinlein <[email protected]>
#
# 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 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 for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
"""Handle GnuPG keys used to trust signed repositories."""
from __future__ import print_function
import os
import os.path
import shutil
import subprocess
import sys
import tempfile
import apt_pkg
from apt_pkg import gettext as _
class AptKeyError(Exception):
pass
class TrustedKey(object):
"""Represents a trusted key."""
def __init__(self, name, keyid, date):
self.raw_name = name
# Allow to translated some known keys
self.name = _(name)
self.keyid = keyid
self.date = date
def __str__(self):
return "%s\n%s %s" % (self.name, self.keyid, self.date)
def _call_apt_key_script(*args, **kwargs):
"""Run the apt-key script with the given arguments."""
conf = None
cmd = [apt_pkg.config.find_file("Dir::Bin::Apt-Key", "/usr/bin/apt-key")]
cmd.extend(args)
env = os.environ.copy()
env["LANG"] = "C"
try:
if apt_pkg.config.find_dir("Dir") != "/":
# If the key is to be installed into a chroot we have to export the
# configuration from the chroot to the apt-key script by using
# a temporary APT_CONFIG file. The apt-key script uses apt-config
# shell internally
conf = tempfile.NamedTemporaryFile(
prefix="apt-key", suffix=".conf")
conf.write(apt_pkg.config.dump().encode("UTF-8"))
conf.flush()
env["APT_CONFIG"] = conf.name
proc = subprocess.Popen(cmd, env=env, universal_newlines=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
content = kwargs.get("stdin", None)
# py2 needs this encoded, py3.3 will crash if it is
if sys.version_info.major < 3 and isinstance(content, unicode):
content = content.encode("utf-8")
output, stderr = proc.communicate(content)
if proc.returncode:
raise AptKeyError(
"The apt-key script failed with return code %s:\n"
"%s\n"
"stdout: %s\n"
"stderr: %s" % (
proc.returncode, " ".join(cmd), output, stderr))
elif stderr:
sys.stderr.write(stderr) # Forward stderr
return output.strip()
finally:
if conf is not None:
conf.close()
def add_key_from_file(filename):
"""Import a GnuPG key file to trust repositores signed by it.
Keyword arguments:
filename -- the absolute path to the public GnuPG key file
"""
if not os.path.abspath(filename):
raise AptKeyError("An absolute path is required: %s" % filename)
if not os.access(filename, os.R_OK):
raise AptKeyError("Key file cannot be accessed: %s" % filename)
_call_apt_key_script("add", filename)
def add_key_from_keyserver(keyid, keyserver):
"""Import a GnuPG key file to trust repositores signed by it.
Keyword arguments:
keyid -- the long keyid (fingerprint) of the key, e.g.
A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553
keyserver -- the URL or hostname of the key server
"""
tmp_keyring_dir = tempfile.mkdtemp()
try:
_add_key_from_keyserver(keyid, keyserver, tmp_keyring_dir)
except:
raise
finally:
shutil.rmtree(tmp_keyring_dir)
def _add_key_from_keyserver(keyid, keyserver, tmp_keyring_dir):
if len(keyid) < (160 / 8):
raise AptKeyError("Only long keyids (v4, 160bit) are supported")
# create a temp keyring dir
tmp_secret_keyring = os.path.join(tmp_keyring_dir, "secring.gpg")
tmp_keyring = os.path.join(tmp_keyring_dir, "pubring.gpg")
# default options for gpg
gpg_default_options = [
"gpg",
"--no-default-keyring", "--no-options",
"--homedir", tmp_keyring_dir,
]
# download the key to a temp keyring first
res = subprocess.call(gpg_default_options + [
"--secret-keyring", tmp_secret_keyring,
"--keyring", tmp_keyring,
"--keyserver", keyserver,
"--recv", keyid,
])
if res != 0:
raise AptKeyError("recv from '%s' failed for '%s'" % (
keyserver, keyid))
# now export again using the long key id (to ensure that there is
# really only this one key in our keyring) and not someone MITM us
tmp_export_keyring = os.path.join(tmp_keyring_dir, "export-keyring.gpg")
res = subprocess.call(gpg_default_options + [
"--keyring", tmp_keyring,
"--output", tmp_export_keyring,
"--export", keyid,
])
if res != 0:
raise AptKeyError("export of '%s' failed", keyid)
# now verify the fingerprint, this is probably redundant as we
# exported by the fingerprint in the previous command but its
# still good paranoia
output = subprocess.Popen(
gpg_default_options + [
"--keyring", tmp_export_keyring,
"--fingerprint",
"--batch",
"--with-colons",
],
stdout=subprocess.PIPE,
universal_newlines=True).communicate()[0]
got_fingerprint = None
for line in output.splitlines():
if line.startswith("fpr:"):
got_fingerprint = line.split(":")[9]
# stop after the first to ensure no subkey trickery
break
# strip the leading "0x" is there is one and uppercase (as this is
# what gnupg is using)
signing_key_fingerprint = keyid.replace("0x", "").upper()
if got_fingerprint != signing_key_fingerprint:
raise AptKeyError(
"Fingerprints do not match, not importing: '%s' != '%s'" % (
signing_key_fingerprint, got_fingerprint))
# finally add it
add_key_from_file(tmp_export_keyring)
def add_key(content):
"""Import a GnuPG key to trust repositores signed by it.
Keyword arguments:
content -- the content of the GnuPG public key
"""
_call_apt_key_script("adv", "--quiet", "--batch",
"--import", "-", stdin=content)
def remove_key(fingerprint):
"""Remove a GnuPG key to no longer trust repositores signed by it.
Keyword arguments:
fingerprint -- the fingerprint identifying the key
"""
_call_apt_key_script("rm", fingerprint)
def export_key(fingerprint):
"""Return the GnuPG key in text format.
Keyword arguments:
fingerprint -- the fingerprint identifying the key
"""
return _call_apt_key_script("export", fingerprint)
def update():
"""Update the local keyring with the archive keyring and remove from
the local keyring the archive keys which are no longer valid. The
archive keyring is shipped in the archive-keyring package of your
distribution, e.g. the debian-archive-keyring package in Debian.
"""
return _call_apt_key_script("update")
def net_update():
"""Work similar to the update command above, but get the archive
keyring from an URI instead and validate it against a master key.
This requires an installed wget(1) and an APT build configured to
have a server to fetch from and a master keyring to validate. APT
in Debian does not support this command and relies on update
instead, but Ubuntu's APT does.
"""
return _call_apt_key_script("net-update")
def list_keys():
"""Returns a list of TrustedKey instances for each key which is
used to trust repositories.
"""
# The output of `apt-key list` is difficult to parse since the
# --with-colons parameter isn't user
output = _call_apt_key_script("adv", "--with-colons", "--batch",
"--list-keys")
res = []
for line in output.split("\n"):
fields = line.split(":")
if fields[0] == "pub":
key = TrustedKey(fields[9], fields[4][-8:], fields[5])
res.append(key)
return res
if __name__ == "__main__":
# Add some known keys we would like to see translated so that they get
# picked up by gettext
lambda: _("Ubuntu Archive Automatic Signing Key <[email protected]>")
lambda: _("Ubuntu CD Image Automatic Signing Key <[email protected]>")
apt_pkg.init()
for trusted_key in list_keys():
print(trusted_key)
# -*- coding: utf-8 -*-
# auth - authentication key management
#
# Copyright (c) 2004 Canonical
# Copyright (c) 2012 Sebastian Heinlein
#
# Author: Michael Vogt <[email protected]>
# Sebastian Heinlein <[email protected]>
#
# 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 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 for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
"""Handle GnuPG keys used to trust signed repositories."""
from __future__ import print_function
import os
import os.path
import shutil
import subprocess
import sys
import tempfile
import apt_pkg
from apt_pkg import gettext as _
class AptKeyError(Exception):
pass
class TrustedKey(object):
"""Represents a trusted key."""
def __init__(self, name, keyid, date):
self.raw_name = name
# Allow to translated some known keys
self.name = _(name)
self.keyid = keyid
self.date = date
def __str__(self):
return "%s\n%s %s" % (self.name, self.keyid, self.date)
def _call_apt_key_script(*args, **kwargs):
"""Run the apt-key script with the given arguments."""
conf = None
cmd = [apt_pkg.config.find_file("Dir::Bin::Apt-Key", "/usr/bin/apt-key")]
cmd.extend(args)
env = os.environ.copy()
env["LANG"] = "C"
try:
if apt_pkg.config.find_dir("Dir") != "/":
# If the key is to be installed into a chroot we have to export the
# configuration from the chroot to the apt-key script by using
# a temporary APT_CONFIG file. The apt-key script uses apt-config
# shell internally
conf = tempfile.NamedTemporaryFile(
prefix="apt-key", suffix=".conf")
conf.write(apt_pkg.config.dump().encode("UTF-8"))
conf.flush()
env["APT_CONFIG"] = conf.name
proc = subprocess.Popen(cmd, env=env, universal_newlines=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
content = kwargs.get("stdin", None)
# py2 needs this encoded, py3.3 will crash if it is
if sys.version_info.major < 3 and isinstance(content, unicode):
content = content.encode("utf-8")
output, stderr = proc.communicate(content)
if proc.returncode:
raise AptKeyError(
"The apt-key script failed with return code %s:\n"
"%s\n"
"stdout: %s\n"
"stderr: %s" % (
proc.returncode, " ".join(cmd), output, stderr))
elif stderr:
sys.stderr.write(stderr) # Forward stderr
return output.strip()
finally:
if conf is not None:
conf.close()
def add_key_from_file(filename):
"""Import a GnuPG key file to trust repositores signed by it.
Keyword arguments:
filename -- the absolute path to the public GnuPG key file
"""
if not os.path.abspath(filename):
raise AptKeyError("An absolute path is required: %s" % filename)
if not os.access(filename, os.R_OK):
raise AptKeyError("Key file cannot be accessed: %s" % filename)
_call_apt_key_script("add", filename)
def add_key_from_keyserver(keyid, keyserver):
"""Import a GnuPG key file to trust repositores signed by it.
Keyword arguments:
keyid -- the long keyid (fingerprint) of the key, e.g.
A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553
keyserver -- the URL or hostname of the key server
"""
tmp_keyring_dir = tempfile.mkdtemp()
try:
_add_key_from_keyserver(keyid, keyserver, tmp_keyring_dir)
except:
raise
finally:
shutil.rmtree(tmp_keyring_dir)
def _add_key_from_keyserver(keyid, keyserver, tmp_keyring_dir):
if len(keyid) < (160 / 8):
raise AptKeyError("Only long keyids (v4, 160bit) are supported")
# create a temp keyring dir
tmp_secret_keyring = os.path.join(tmp_keyring_dir, "secring.gpg")
tmp_keyring = os.path.join(tmp_keyring_dir, "pubring.gpg")
# default options for gpg
gpg_default_options = [
"gpg",
"--no-default-keyring", "--no-options",
"--homedir", tmp_keyring_dir,
]
# download the key to a temp keyring first
res = subprocess.call(gpg_default_options + [
"--secret-keyring", tmp_secret_keyring,
"--keyring", tmp_keyring,
"--keyserver", keyserver,
"--recv", keyid,
])
if res != 0:
raise AptKeyError("recv from '%s' failed for '%s'" % (
keyserver, keyid))
# now export again using the long key id (to ensure that there is
# really only this one key in our keyring) and not someone MITM us
tmp_export_keyring = os.path.join(tmp_keyring_dir, "export-keyring.gpg")
res = subprocess.call(gpg_default_options + [
"--keyring", tmp_keyring,
"--output", tmp_export_keyring,
"--export", keyid,
])
if res != 0:
raise AptKeyError("export of '%s' failed", keyid)
# now verify the fingerprint, this is probably redundant as we
# exported by the fingerprint in the previous command but its
# still good paranoia
output = subprocess.Popen(
gpg_default_options + [
"--keyring", tmp_export_keyring,
"--fingerprint",
"--batch",
"--with-colons",
],
stdout=subprocess.PIPE,
universal_newlines=True).communicate()[0]
got_fingerprint = None
for line in output.splitlines():
if line.startswith("fpr:"):
got_fingerprint = line.split(":")[9]
# stop after the first to ensure no subkey trickery
break
# strip the leading "0x" is there is one and uppercase (as this is
# what gnupg is using)
signing_key_fingerprint = keyid.replace("0x", "").upper()
if got_fingerprint != signing_key_fingerprint:
raise AptKeyError(
"Fingerprints do not match, not importing: '%s' != '%s'" % (
signing_key_fingerprint, got_fingerprint))
# finally add it
add_key_from_file(tmp_export_keyring)
def add_key(content):
"""Import a GnuPG key to trust repositores signed by it.
Keyword arguments:
content -- the content of the GnuPG public key
"""
_call_apt_key_script("adv", "--quiet", "--batch",
"--import", "-", stdin=content)
def remove_key(fingerprint):
"""Remove a GnuPG key to no longer trust repositores signed by it.
Keyword arguments:
fingerprint -- the fingerprint identifying the key
"""
_call_apt_key_script("rm", fingerprint)
def export_key(fingerprint):
"""Return the GnuPG key in text format.
Keyword arguments:
fingerprint -- the fingerprint identifying the key
"""
return _call_apt_key_script("export", fingerprint)
def update():
"""Update the local keyring with the archive keyring and remove from
the local keyring the archive keys which are no longer valid. The
archive keyring is shipped in the archive-keyring package of your
distribution, e.g. the debian-archive-keyring package in Debian.
"""
return _call_apt_key_script("update")
def net_update():
"""Work similar to the update command above, but get the archive
keyring from an URI instead and validate it against a master key.
This requires an installed wget(1) and an APT build configured to
have a server to fetch from and a master keyring to validate. APT
in Debian does not support this command and relies on update
instead, but Ubuntu's APT does.
"""
return _call_apt_key_script("net-update")
def list_keys():
"""Returns a list of TrustedKey instances for each key which is
used to trust repositories.
"""
# The output of `apt-key list` is difficult to parse since the
# --with-colons parameter isn't user
output = _call_apt_key_script("adv", "--with-colons", "--batch",
"--list-keys")
res = []
for line in output.split("\n"):
fields = line.split(":")
if fields[0] == "pub":
key = TrustedKey(fields[9], fields[4][-8:], fields[5])
res.append(key)
return res
if __name__ == "__main__":
# Add some known keys we would like to see translated so that they get
# picked up by gettext
lambda: _("Ubuntu Archive Automatic Signing Key <[email protected]>")
lambda: _("Ubuntu CD Image Automatic Signing Key <[email protected]>")
apt_pkg.init()
for trusted_key in list_keys():
print(trusted_key)