~ubuntu-branches/ubuntu/raring/hplip/raring

« back to all changes in this revision

Viewing changes to base/pkit.py

  • Committer: Bazaar Package Importer
  • Author(s): Mark Purcell
  • Date: 2009-12-14 20:08:44 UTC
  • mfrom: (2.1.118 lucid)
  • Revision ID: james.westby@ubuntu.com-20091214200844-z8qhqwgppbu3t7ze
Tags: 3.9.10-4
KBSD patch from KiBi (Closes: #560796)

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
import dbus.service
42
42
import gobject
43
43
 
 
44
import warnings
 
45
# Ignore: .../dbus/connection.py:242: DeprecationWarning: object.__init__() takes no parameters
 
46
# (occurring on Python 2.6/dBus 0.83/Ubuntu 9.04)
 
47
warnings.simplefilter("ignore", DeprecationWarning)
 
48
 
44
49
 
45
50
class AccessDeniedException(dbus.DBusException):
46
51
    _dbus_error_name = 'com.hp.hplip.AccessDeniedException'
125
130
 
126
131
 
127
132
class PolicyKitService(dbus.service.Object):
128
 
    def check_permission(self, sender, action=POLICY_KIT_ACTION):
 
133
    def check_permission_v0(self, sender, action=POLICY_KIT_ACTION):
129
134
        if not sender:
130
 
            log.syslog("Session not authorized by PolicyKit")
 
135
            log.error("Session not authorized by PolicyKit")
131
136
            raise AccessDeniedException('Session not authorized by PolicyKit')
132
137
 
133
138
        try:
141
146
 
142
147
            granted = policy_auth.is_authorized(action, pid)
143
148
            if not granted:
144
 
                log.syslog("Process not authorized by PolicyKit")
 
149
                log.error("Process not authorized by PolicyKit")
145
150
                raise AccessDeniedException('Process not authorized by PolicyKit')
146
151
 
147
152
            granted = policy_auth.policy_kit.IsSystemBusNameAuthorized(action,
148
153
                                                                       sender,
149
154
                                                                       False)
150
155
            if granted != 'yes':
151
 
                log.syslog("Session not authorized by PolicyKit")
 
156
                log.error("Session not authorized by PolicyKit version 0")
152
157
                raise AccessDeniedException('Session not authorized by PolicyKit')
153
158
 
154
159
        except AccessDeniedException:
160
165
            raise AccessDeniedException(ex.message)
161
166
 
162
167
 
163
 
 
164
 
class BackendService(PolicyKitService):
165
 
    INTERFACE_NAME = 'com.hp.hplip'
166
 
    SERVICE_NAME   = 'com.hp.hplip'
167
 
    IDLE_TIMEOUT   =  30
168
 
 
169
 
    def __init__(self, connection=None, path='/'):
170
 
        if connection is None:
171
 
            connection = get_service_bus()
172
 
 
173
 
        super(BackendService, self).__init__(connection, path)
174
 
 
175
 
        self.name = dbus.service.BusName(self.SERVICE_NAME, connection)
176
 
        self.loop = gobject.MainLoop()
177
 
 
178
 
 
179
 
    def run(self):
180
 
        log.debug("Starting back-end service loop")
181
 
#       self.start_idle_timeout()
182
 
        self.loop.run()
183
 
 
184
 
    @dbus.service.method(dbus_interface=INTERFACE_NAME,
185
 
                            in_signature='s', out_signature='b',
186
 
                            sender_keyword='sender')
187
 
    def installPlugin(self, src_dir, sender=None):
188
 
        try:
189
 
            self.check_permission(sender, INSTALL_PLUGIN_ACTION)
190
 
        except AccessDeniedException, e:
191
 
            return False
192
 
 
193
 
        log.debug("installPlugin: received '%s'" % src_dir)
194
 
 
195
 
        if not copyPluginFiles(src_dir):
196
 
            log.syslog("Plugin installation failed")
197
 
            return False
198
 
 
199
 
        return True
200
 
 
201
 
 
202
 
    @dbus.service.method(dbus_interface=INTERFACE_NAME,
203
 
                            in_signature='', out_signature='b',
204
 
                            sender_keyword='sender')
205
 
    def shutdown(self, sender=None):
206
 
        log.debug("Stopping backend service")
207
 
        self.loop.quit()
208
 
 
209
 
        return True
 
168
    def check_permission_v1(self, sender, connection, action=POLICY_KIT_ACTION):
 
169
        if not sender or not connection:
 
170
            log.error("Session not authorized by PolicyKit")
 
171
            raise AccessDeniedException('Session not authorized by PolicyKit')
 
172
 
 
173
        system_bus = dbus.SystemBus()
 
174
        obj = system_bus.get_object("org.freedesktop.PolicyKit1",
 
175
                                    "/org/freedesktop/PolicyKit1/Authority",
 
176
                                    "org.freedesktop.PolicyKit1.Authority")
 
177
        policy_kit = dbus.Interface(obj, "org.freedesktop.PolicyKit1.Authority")
 
178
        info = dbus.Interface(connection.get_object("org.freedesktop.DBus",
 
179
                                                    "/org/freedesktop/DBus/Bus",
 
180
                                                    False),
 
181
                              "org.freedesktop.DBus")
 
182
        pid = info.GetConnectionUnixProcessID(sender)
 
183
        
 
184
        subject = (
 
185
            'unix-process',
 
186
            { 'pid' : dbus.UInt32(pid, variant_level = 1) }
 
187
        )
 
188
        details = { '' : '' }
 
189
        flags = dbus.UInt32(1)         # AllowUserInteraction = 0x00000001
 
190
        cancel_id = ''
 
191
 
 
192
        (ok, notused, details) = \
 
193
            policy_kit.CheckAuthorization(subject,
 
194
                                          action,
 
195
                                          details,
 
196
                                          flags,
 
197
                                          cancel_id)
 
198
        if not ok:
 
199
            log.error("Session not authorized by PolicyKit version 1")
 
200
 
 
201
        return ok
 
202
 
 
203
 
 
204
if utils.to_bool(sys_conf.get('configure', 'policy-kit')):
 
205
    class BackendService(PolicyKitService):
 
206
        INTERFACE_NAME = 'com.hp.hplip'
 
207
        SERVICE_NAME   = 'com.hp.hplip'
 
208
        LOGFILE_NAME   = '/tmp/hp-pkservice.log'
 
209
 
 
210
        def __init__(self, connection=None, path='/', logfile=LOGFILE_NAME):
 
211
            if connection is None:
 
212
                connection = get_service_bus()
 
213
 
 
214
            super(BackendService, self).__init__(connection, path)
 
215
 
 
216
            self.name = dbus.service.BusName(self.SERVICE_NAME, connection)
 
217
            self.loop = gobject.MainLoop()
 
218
            self.version = 0
 
219
 
 
220
            log.set_logfile("%s.%d" % (logfile, os.getpid()))
 
221
            log.set_level("debug")
 
222
 
 
223
        def run(self, version=None):
 
224
            if version is None:
 
225
                version = policykit_version()
 
226
                if version is None:
 
227
                    log.error("Unable to determine installed PolicyKit version")
 
228
                    return
 
229
 
 
230
            self.version = version
 
231
            log.set_where(Logger.LOG_TO_CONSOLE_AND_FILE)
 
232
            log.debug("Starting back-end service loop (version %d)" % version)
 
233
 
 
234
            self.loop.run()
 
235
 
 
236
 
 
237
        @dbus.service.method(dbus_interface=INTERFACE_NAME,
 
238
                                in_signature='s', out_signature='b',
 
239
                                sender_keyword='sender',
 
240
                                connection_keyword='connection')
 
241
        def installPlugin(self, src_dir, sender=None, connection=None):
 
242
            if self.version == 0:
 
243
                try:
 
244
                    self.check_permission_v0(sender, INSTALL_PLUGIN_ACTION)
 
245
                except AccessDeniedException, e:
 
246
                    return False
 
247
 
 
248
            elif self.version == 1:
 
249
                if not self.check_permission_v1(sender,
 
250
                                                connection,
 
251
                                                INSTALL_PLUGIN_ACTION):
 
252
                    return False
 
253
 
 
254
            else:
 
255
                log.error("installPlugin: invalid PolicyKit version %d" % self.version)
 
256
                return False
 
257
 
 
258
            log.debug("installPlugin: installing from '%s'" % src_dir)
 
259
 
 
260
            if not copyPluginFiles(src_dir):
 
261
                log.error("Plugin installation failed")
 
262
                return False
 
263
 
 
264
            return True
 
265
 
 
266
 
 
267
        @dbus.service.method(dbus_interface=INTERFACE_NAME,
 
268
                                in_signature='s', out_signature='b',
 
269
                                sender_keyword='sender',
 
270
                                connection_keyword='connection')
 
271
        def shutdown(self, arg, sender=None, connection=None):
 
272
            log.debug("Stopping backend service")
 
273
            self.loop.quit()
 
274
 
 
275
            return True
210
276
 
211
277
 
212
278
 
213
279
class PolicyKit(object):
214
 
    def __init__(self):
 
280
    def __init__(self, version=None):
 
281
        if version is None:
 
282
            version = policykit_version()
 
283
            if version is None:
 
284
                log.debug("Unable to determine installed PolicyKit version")
 
285
                return
 
286
 
215
287
        self.bus = dbus.SystemBus()
216
288
        self.obj = self.bus.get_object(POLICY_KIT_ACTION, "/")
217
289
        self.iface = dbus.Interface(self.obj, dbus_interface=POLICY_KIT_ACTION)
218
 
 
 
290
        self.version = version
219
291
 
220
292
    def installPlugin(self, src_dir):
221
 
        auth = PolicyKitAuthentication()
222
 
        if not auth.is_authorized(INSTALL_PLUGIN_ACTION):
223
 
            if not auth.obtain_authorization(INSTALL_PLUGIN_ACTION):
224
 
                return None
 
293
        if self.version == 0:
 
294
            auth = PolicyKitAuthentication()
 
295
            if not auth.is_authorized(INSTALL_PLUGIN_ACTION):
 
296
                if not auth.obtain_authorization(INSTALL_PLUGIN_ACTION):
 
297
                    return None
225
298
 
226
299
        try:
227
300
            ok = self.iface.installPlugin(src_dir)
232
305
 
233
306
 
234
307
    def shutdown(self):
235
 
        auth = PolicyKitAuthentication()
236
 
        if not auth.is_authorized(INSTALL_PLUGIN_ACTION):
237
 
            if not auth.obtain_authorization(INSTALL_PLUGIN_ACTION):
238
 
                return None
 
308
        if self.version == 0:
 
309
            auth = PolicyKitAuthentication()
 
310
            if not auth.is_authorized(INSTALL_PLUGIN_ACTION):
 
311
                if not auth.obtain_authorization(INSTALL_PLUGIN_ACTION):
 
312
                    return None
239
313
 
240
314
        try:
241
 
            ok = self.iface.shutdown()
 
315
            ok = self.iface.shutdown("")
242
316
            return ok
243
317
        except dbus.DBusException, e:
244
318
            log.debug("shutdown: %s" % str(e))
282
356
        for s in plugin_spec.get("products", PRODUCT).split(','):
283
357
 
284
358
            if not plugin_spec.has_section(s):
285
 
                log.syslog("Missing section [%s]" % s)
 
359
                log.error("Missing section [%s]" % s)
286
360
                return False
287
361
 
288
362
            src = plugin_spec.get(s, 'src', '')
290
364
            link = plugin_spec.get(s, 'link', '')
291
365
 
292
366
            if not src:
293
 
                log.syslog("Missing 'src=' value in section [%s]" % s)
 
367
                log.error("Missing 'src=' value in section [%s]" % s)
294
368
                return False
295
369
 
296
370
            if not trg:
297
 
                log.syslog("Missing 'trg=' value in section [%s]" % s)
 
371
                log.error("Missing 'trg=' value in section [%s]" % s)
298
372
                return False
299
373
 
300
374
            src = os.path.basename(utils.cat(src))
327
401
            os.makedirs(trg_dir, 0755)
328
402
 
329
403
        if not os.path.isdir(trg_dir):
330
 
            log.syslog("Target directory %s exists but is not a directory. Skipping." % trg_dir)
 
404
            log.error("Target directory %s exists but is not a directory. Skipping." % trg_dir)
331
405
            continue
332
406
 
333
407
        try:
334
408
            shutil.copyfile(src, trg)
335
409
        except (IOError, OSError), e:
336
 
            log.syslog("File copy failed: %s" % e.strerror)
 
410
            log.error("File copy failed: %s" % e.strerror)
337
411
            continue
338
412
 
339
413
        else:
340
414
            if not os.path.exists(trg):
341
 
                log.syslog("Target file %s does not exist. File copy failed." % trg)
 
415
                log.error("Target file %s does not exist. File copy failed." % trg)
342
416
                continue
343
417
            else:
344
418
                os.chmod(trg, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH)
365
439
    return True
366
440
 
367
441
 
368
 
def run_plugin_command(required=True):
 
442
def run_plugin_command(required=True, plugin_reason=PLUGIN_REASON_NONE):
369
443
    su_sudo = None
370
444
    need_sudo = True
371
445
 
386
460
        su_sudo = utils.su_sudo()
387
461
        if su_sudo is None:
388
462
            log.error("Unable to find a suitable sudo command to run 'hp-plugin'")
389
 
            return False
 
463
            return (False, False)
390
464
 
391
465
    req = '--required'
392
466
    if not required:
393
467
        req = '--optional'
394
468
 
395
469
    if utils.which("hp-plugin"):
396
 
        cmd = su_sudo % ("hp-plugin -u %s" % req)
 
470
        cmd = su_sudo % ("hp-plugin -u %s --reason %s" % (req, plugin_reason))
397
471
    else:
398
 
        cmd = su_sudo % ("python ./plugin.py -u %s" % req)
 
472
        cmd = su_sudo % ("python ./plugin.py -u %s --reason %s" % (req, plugin_reason))
399
473
 
400
474
    log.debug("%s" % cmd)
401
475
    status, output = utils.run(cmd, log_output=True, password_func=None, timeout=1)
402
476
 
403
 
    return status == 0
 
477
    return (status == 0, True)
 
478
 
 
479
 
 
480
def policykit_version():
 
481
    if os.path.isdir("/usr/share/polkit-1"):
 
482
        return 1
 
483
    elif os.path.isdir("/usr/share/PolicyKit"):
 
484
        return 0
 
485
    else:
 
486
        return None