Dbus and PolicyKit instance (Python) () goto

Source: Internet
Author: User
Tags goto time zones root access python decorator

The program that uses PolicyKit usually has a Dbus daemon program to complete the related operation, this Dbus daemon will register a system bus service name, in response to request root privileged operation, When the Dbus request arrives, it verifies that the requestor has the appropriate permissions to invoke the operation (method), which is defined in the. conf file (described later).

First define the system Dbus daemon, write a. service file to launch our daemon

Org.example.foo.service

File Placement Directory:/usr/share/dbus-1/system-services

1 [D-bus Service]
2 Name=org.example.foo
3 exec=/usr/local/libexec/policykit_dbus_foo_daemon.py
4 User=root

Where name is the registered Systembus service name

Exec is the path where the daemon program is located

We're starting with root privileges.

When a program requests the Org.example.foo service, the system will automatically start our daemon with root.

For information see here D-bus system Bus activation

Note: Sessionbus's ' org.freedesktop.PolicyKit.AuthenticationAgent ' service is automatically activated only when the authentication is requested, and is automatically turned off after a period of time.

And look at our daemon program.

policykit_dbus_foo_daemon.py

File Placement Directory:/usr/local/libexec

1 #!/usr/bin/python
2 #-*-Coding:utf-8-*-
3 "" "
4 Author:joe.zhou
5 "" "
6 Import OS
7 Import Sys
8 Import GObject
9 Import Dbus
Ten Import Dbus.service
Import Dbus.mainloop.glib
12
Class Notprivilegedexception (Dbus. Dbusexception):
_dbus_error_name = "Org.example.foo.dbus.service.PolKit.NotPrivilegedException"
def __init__ (self, action_id, *p, **k):
Self._dbus_error_name = Self.__class__._dbus_error_name + "." + action_id
+ Super (notprivilegedexception, self). __init__ (*p, **k)
18
def require_auth (action_id):
def require_auth_decorator (func):
def _func (*args,**kwds):
Revoke_if_one_shot = True
System_bus = Dbus. Systembus ()
Auth_obj = System_bus.get_object (' org.freedesktop.PolicyKit ', '/')
Auth_interface = Dbus. Interface (auth_obj, ' org.freedesktop.PolicyKit ')
-Try:
Dbus_name = kwds[' Sender_keyword ']
Except:
Raise Notprivilegedexception (ACTION_ID)
granted = Auth_interface. Issystembusnameauthorized (Action_id,dbus_name,revoke_if_one_shot)
If granted! = ' Yes ':
Raise Notprivilegedexception (ACTION_ID)
33
return func (*args,**kwds)
35
_func.func_name = Func.func_name
PNS _func.__name__ = func.__name__
_func.__doc__ = func.__doc__
_func return
Require_auth_decorator return
41
42 ""
A D-bus Service that PolicyKit Controls access to.
44 ""
Class Policykitfoomechanism (Dbus.service.Object):
service_name = ' Org.example.foo '
Service_path = '/org/example/foo '
interface_name = ' Org.example.foo '
49
def __init__ (self, conn, Object_path=service_path):
Wuyi dbus.service.object.__init__ (SELF, conn, Object_path)
52
@dbus. Service.method (Dbus_interface=interface_name, in_signature= ' ss ', out_signature= ' s ', sender_keyword= ' Sender ')
WriteFile def (self, filepath, Contents,sender=none):
55 ""
The contents to a file, requires Sudo/root access to doing so.
PolicyKit won't allow this function to be called without sudo/root
Authenticate access, and would ask the user to the if necessary, when
The application calls PolicyKit ' s obtainauthentication ().
60 ""
@require_auth (' org.example.foo.modify ')
+ def _write_file (Filepath,contents,sender_keyword = None):
+ F = open (filepath, ' W ')
F.write (contents)
F.close ()
The return ' done '
_write_file return (Filepath,contents,sender_keyword = sender)
68
@dbus. Service.method (Dbus_interface=interface_name, in_signature= ' s ', out_signature= ' as ', sender_keyword= ' Sender ')
Runcmd def (self, Cmdstr, Sender=none):
@require_auth (' Org.example.foo.sys ')
_run_cmd def (Cmdstr,sender_keyword = None):
Os.popen f = (CMDSTR)
A. Output = F.readlines ()
F.close ()
Return output
_run_cmd return (Cmdstr,sender_keyword = sender)
78
@dbus. Service.method (dbus_interface=interface_name,in_signature= ", out_signature=", sender_keyword= ' sender ')
def Exit (self, Sender=none):
Bayi @require_auth (' Org.example.foo.sys ')
_exit def (Sender_keyword = None):
Loop.quit ()
_exit return (Sender_keyword = sender)
85
@dbus. Service.method (dbus_interface=interface_name,in_signature= ", out_signature= ' s ')
def hello (self):
The return ' Hello '
89
if __name__ = = ' __main__ ':
Dbus.mainloop.glib.DBusGMainLoop (Set_as_default=true)
The Dbus bus =. Systembus ()
Name = Dbus.service.BusName (policykitfoomechanism.service_name, bus)
94 The_object = Policykitfoomechanism (BUS)
The loop = GObject. Mainloop ()
Loop.run ()
97
98

Three operations are defined in the daemon program that require permissions, an operation that does not require permissions, and an action ID that defines how the operation (method) requires validation. The program asks the org.freedesktop.PolicyKit.AuthenticationAgent to request the corresponding Action ID permission before it can be called.

Otherwise you will be prompted not to have permission, the Hello operation does not require permission to operate, the difference is whether to request the first to Org.freedesktop.Policykit detect this dbus please ask if there is previleged.

Call the Issystembusnameauthorized method to verify that the pass returns ' Yes ', otherwise the other string is returned

Use the command below to view the issystembusnameauthorized details of the method Introspec

Dbus-send--system--print-reply--dest=org.freedesktop.policykit/org.freedesktop.dbus.introspectable.introspect

It is worth noting here that if you define a series of system-level invoke operations (starting with the previous program as root, but removing the previous @require_auth section), you must ensure that each operation is authenticated with permission, that is, add this thing @require_auth (' Org.example.foo.sys ')

If you define the Dbus operation of the write file, but do not perform permission validation, an ordinary user's Dbus call will also be called through, that is, ordinary users can arbitrarily overwrite any file, which is very dangerous

You can also try to remove the previous @require_auth section, and then start the service, and use D-feet to invoke the WriteFile method to write the file at random on the root directory

--Off-topic-

I wanted to write the procedure in this form.

1 @require_auth (' Org.example.foo.sys ')
2 @dbus. Service.method (dbus_interface=interface_name,in_signature= ", out_signature=", sender_keyword= ' sender ')
3 def Exit (self, Sender=none):
4 Loop.quit ()

This writing, with D-feet looked under, service does not come, adjusted for a long time also can not find out the reason, but write this kind of redundant way--!, see can have expert guidance under, not grateful!!

Then define who can invoke these operations (methods) in the. conf file definition

Org.example.foo.conf

File Placement Directory:/ETC/DBUS-1/SYSTEM.D

1 <?xml version= "1.0" encoding= "UTF-8"?> <!---*-XML-*--
2
3 <! DOCTYPE Busconfig Public
4 "-//freedesktop//dtd D-bus BUS Configuration 1.0//en"
5 "HTTP://WWW.FREEDESKTOP.ORG/STANDARDS/DBUS/1.0/BUSCONFIG.DTD" >
6 <busconfig>
7
8 <!--only Root can own the service--
9 <policy user= "root" >
Ten <allow own= "Org.example.foo"/>
One <allow send_interface= "Org.example.foo"/>
</policy>
13
<!--allow introspectable-->< can be called by anyone, using. Policy in the later.
<policy context= "Default" >
<allow send_interface= "Org.example.foo"/>
<allow send_interface= "Org.freedesktop.DBus.Introspectable"/>
</policy>
19
</busconfig>
21st

followed by the definition of the associated action ID, defined in the. policy file

which defines the way and time of authorization authentication can have the following several

No
auth_self$$
auth_admin$$
Yes

Where add $$ can append suffix _one_shot,_keep_session,_keep_always
Its meaning is literally clear.

You can also see man policykit.conf

Can't write? Refer to the/usr/share/policykit/policy directory for a heap of. policy files.

After writing, you can use the tool polkit-policy-file-validate to verify that it is valid.

Org.example.foo.policy

File Placement Directory:/usr/share/policykit/policy

1 <?xml version= "1.0" encoding= "UTF-8"?>
2 <! DOCTYPE Policyconfig Public
3 "-//freedesktop//dtd PolicyKit Policy Configuration 1.0//en"
4 "HTTP://WWW.FREEDESKTOP.ORG/STANDARDS/POLICYKIT/1.0/POLICYCONFIG.DTD" >
5 <policyconfig>
6
7 <vendor>example application</vendor>
8 <vendor_url>http://fedoraproject.org/example</vendor_url>
9
Ten <action id= "Org.example.foo.modify" >
<description>example Write access</description>
<message>system policy prevents write access to the Example service</message>
<defaults>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
18
<action id= "Org.example.foo.sys" >
<description>example system action</description>
<message>system policy prevents do System action to the Example service</message>
<defaults>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
27
28
</policyconfig>

Do the above work, we can write our call-end program

1 #!/usr/bin/python
2 #-*-Coding:utf-8-*-
3 Import OS
4 Import Sys
5 Import GObject
6 Import Dbus
7 Import Dbus.service
8 Import Dbus.mainloop.glib
9 Import Traceback
10
def auth_proxy (func):
Dbusname = ' org.freedesktop.PolicyKit.AuthenticationAgent '
Dbuspath = '/'
Dbusinterface = ' org.freedesktop.PolicyKit.AuthenticationAgent '
Exc_name = "Org.example.foo.dbus.service.PolKit.NotPrivilegedException"
def auth_proxy_wrapper (*args, **kwds):
Try:
return func (*args, **kwds)
Except Dbus. Dbusexception, E:
Exc_name = E.get_dbus_name ()
If Exc_name.startswith (Exc_name + "."):
Session_bus = Dbus. Sessionbus ()
Auth_obj = Session_bus.get_object (Dbusname, Dbuspath)
Auth_interface = Dbus. Interface (Auth_obj,dbusinterface)
action_id = Exc_name[len (exc_name) + 1:]
granted = Auth_interface. Obtainauthorization (action_id, Dbus. UInt32 (0), Dbus. UInt32 (Os.getpid ()))
If not granted:
Raise
else:
Raise
31
return func (*args, **kwds)
Return Auth_proxy_wrapper
34
Class Dbustestproxy:
service_name = ' Org.example.foo '
PNS Service_path = '/org/example/foo '
interface_name = ' Org.example.foo '
__init__ def (self):
Self.bus = Dbus. Systembus ()
SELF.O = Self.bus.get_object (self. Service_name,self. Service_path)
SELF.I = Dbus. Interface (self.o,self. Interface_name)
43
@auth_proxy
def writefilewithauth (self,filepath,contents):
Self.i.writefile return (filepath,contents)
47
def writefilewithoutauth (self,filepath,contents):
Self.i.writefile return (filepath,contents)
50
Wuyi @auth_proxy
Runcmd def (SELF,CMDSTR):
Self.i.runcmd return (CMDSTR)
54
@auth_proxy
+ def Exit (self):
Self.i.exit return ()
58
#do need to Auth
def hello (self):
Self.i.hello return ()
62
63
if __name__ = = "__main__":
p = dbustestproxy ()
#print p.runcmd (' Ls-al ')
P.writefilewithauth print ('/text ', ' test\n ')
#print P.writefilewithoutauth ('/text ', ' test\n ')
#p. Exit ()
Print P.hello ()

Run the above program to try the Writefilewithauth method will pop up the verification dialog box, the password is correct in the root directory will be written to the file, call Writefilewithoutauth because there is no call permission validation

Instead, returns an exception with no privileged, because the WriteFile operation requires permission.

The above procedure is quite simple, because I am also a novice python, I believe you can see clearly.

Finally, make a package, click Download policykit_dbus_foo.7z

#install
sudo./install.sh Install

#remove
sudo./install.sh Uninstall

#test
./policykit_dbus_foo_client.py

The above system environment is Ubuntu 8.04

Reference:


Http://hal.freedesktop.org/docs/PolicyKit

Policy, mechanism and time zones

Http://dbus.freedesktop.org/doc/dbus-specification.html

Http://dbus.freedesktop.org/doc/dbus-python/doc/tutorial.html

Python Decorator for functions and methods

Finally found an open source project Python-slip

The slip.dbus.polkit section, which encapsulates the policykit, makes it easier to use PolicyKit in your project. I think Python is simple enough. Orz)

NOTE: Reprint Annotated source

Http://www.cnblogs.com/joe2k8/archive/2009/05/24/1488074.html

Dbus and PolicyKit instance (Python) () goto

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.