~ubuntu-branches/ubuntu/precise/aptdaemon/precise-updates

« back to all changes in this revision

Viewing changes to aptdaemon/worker.py

  • Committer: Package Import Robot
  • Author(s): Michael Vogt
  • Date: 2011-11-18 12:03:22 UTC
  • mfrom: (1.3.15)
  • Revision ID: package-import@ubuntu.com-20111118120322-x0ffrgyrrc7ku8lm
Tags: 0.43+bzr703-0ubuntu1
* New bzr snapshot:
  - Merge the AddLicenseKey method
  - Replace the backported unittest2 framework by the native one of
    Python 2.7 and Nose to collect the tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
# core.Transaction.gettext
62
62
_ = lambda s: s
63
63
 
 
64
 
64
65
class AptWorker(gobject.GObject):
65
66
 
66
67
    """Worker which processes transactions from the queue."""
69
70
                                        gobject.TYPE_NONE,
70
71
                                        (gobject.TYPE_PYOBJECT,))}
71
72
 
 
73
    # the basedir under which license keys can be stored
 
74
    LICENSE_KEY_ROOTDIR = "/opt/"
 
75
 
72
76
    def __init__(self, chroot=None):
73
77
        """Initialize a new AptWorker instance."""
74
78
        gobject.GObject.__init__(self)
113
117
        dists, errors = pkg_resources.working_set.find_plugins(env)
114
118
        for dist in dists:
115
119
            pkg_resources.working_set.add(dist)
116
 
        for name in ["modify_cache_after", "modify_cache_before"]:
 
120
        for name in ["modify_cache_after", "modify_cache_before",
 
121
                     "get_license_key"]:
117
122
            for ept in pkg_resources.iter_entry_points("aptdaemon.plugins",
118
123
                                                       name):
119
124
                try:
204
209
            elif trans.role == ROLE_UPDATE_CACHE:
205
210
                self.update_cache(trans, **trans.kwargs)
206
211
            # Process the transactions which require a consistent cache
 
212
            elif trans.role == ROLE_ADD_LICENSE_KEY:
 
213
                self.add_license_key(trans, **trans.kwargs)
207
214
            elif self._cache and self._cache.broken_count:
208
215
                broken = [pkg.name for pkg in self._cache if pkg.is_now_broken]
209
216
                raise TransactionFailed(ERROR_CACHE_BROKEN,
1174
1181
                    log.debug("Removing file %s", path)
1175
1182
                    os.remove(path)
1176
1183
 
 
1184
    def add_license_key(self, trans, pkg_name, json_token, server_name):
 
1185
        """Add a license key data to the given package.
 
1186
 
 
1187
        Keyword arguemnts:
 
1188
        trans -- the coresponding transaction
 
1189
        pkg_name -- the name of the corresponding package
 
1190
        json_token -- the oauth token as json
 
1191
        server_name -- the server to use (ubuntu-production, ubuntu-staging)
 
1192
        """
 
1193
        # set transaction state to downloading
 
1194
        trans.status = STATUS_DOWNLOADING
 
1195
        try:
 
1196
            license_key, license_key_path = \
 
1197
                    self.plugins["get_license_key"][0](trans.uid, pkg_name,
 
1198
                                                       json_token, server_name)
 
1199
        except Exception, error:
 
1200
            raise TransactionFailed(ERROR_LICENSE_KEY_DOWNLOAD_FAILED,
 
1201
                                    str(error))
 
1202
        # ensure stuff is good
 
1203
        if not license_key_path or not license_key:
 
1204
            raise TransactionFailed(ERROR_LICENSE_KEY_DOWNLOAD_FAILED,
 
1205
                                    _("The license key is empty"))
 
1206
 
 
1207
        # add license key if we have one
 
1208
        self._add_license_key_to_system(pkg_name, license_key, license_key_path)
 
1209
 
 
1210
    def _add_license_key_to_system(self, pkg_name, license_key, license_key_path):
 
1211
        # fixup path
 
1212
        license_key_path = os.path.join(apt_pkg.config.find_dir("Dir"),
 
1213
                                        license_key_path.lstrip("/"))
 
1214
 
 
1215
        # Check content of the key
 
1216
        if (license_key.strip().startswith("#!") or
 
1217
            license_key.startswith("\x7fELF")):
 
1218
            raise TransactionFailed(ERROR_LICENSE_KEY_INSTALL_FAILED,
 
1219
                                    _("The license key is not allowed to "
 
1220
                                      "contain executable code."))
 
1221
        # Check the path of the license
 
1222
        license_key_path = os.path.normpath(license_key_path)
 
1223
        license_key_path_rootdir = os.path.join(apt_pkg.config["Dir"],
 
1224
                                           self.LICENSE_KEY_ROOTDIR.lstrip("/"),
 
1225
                                           pkg_name)
 
1226
        if not license_key_path.startswith(license_key_path_rootdir):
 
1227
            raise TransactionFailed(ERROR_LICENSE_KEY_INSTALL_FAILED,
 
1228
                                    _("The license key path %s is invalid"),
 
1229
                                    license_key_path)
 
1230
        if os.path.lexists(license_key_path):
 
1231
            raise TransactionFaild(ERROR_LICENSE_KEY_INSTALL_FAILED,
 
1232
                                   _("The license key already exists: %s"),
 
1233
                                   license_key_path)
 
1234
        # Symlink attacks!
 
1235
        if os.path.realpath(license_key_path) != license_key_path:
 
1236
            raise TransactionFailed(ERROR_LICENSE_KEY_INSTALL_FAILED,
 
1237
                                   _("The location of the license key is "
 
1238
                                     "unsecure since it contains symbolic "
 
1239
                                     "links. The path %s maps to %s"),
 
1240
                                     license_key_path,
 
1241
                                     os.path.realpath(licese_key_path))
 
1242
        # Check if the directory already exists
 
1243
        if not os.path.isdir(os.path.dirname(license_key_path)):
 
1244
            raise TransactionFailed(ERROR_LICENSE_KEY_INSTALL_FAILED,
 
1245
                                   _("The directory where to install the key "
 
1246
                                     "to doesn't exist yet: %s"),
 
1247
                                   license_key_path)
 
1248
        # write it
 
1249
        log.info("Writing license key to '%s'" % license_key_path)
 
1250
        old_umask = os.umask(18)
 
1251
        try:
 
1252
            with open(license_key_path, "w") as license_file:
 
1253
                license_file.write(license_key)
 
1254
        except IOError:
 
1255
            raise TransactionFailed(ERROR_LICENSE_KEY_INSTALL_FAILED,
 
1256
                                    _("Failed to write key file to: %s"),
 
1257
                                    license_key_path)
 
1258
        finally:
 
1259
            os.umask(old_umask)
 
1260
 
1177
1261
    def _get_broken_details(self, trans, now=True):
1178
1262
        """Return a message which provides debugging information about
1179
1263
        broken packages.