3
# (c) 2008 Canonical Ltd.
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License along
16
# with this program; if not, write to the Free Software Foundation, Inc.,
17
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23
import dbus.mainloop.glib
26
from UbuntuSystemService.utils import *
28
class UnknownProxyTypeError(dbus.DBusException):
29
" a unknown proxy type was passed "
31
class PermissionDeniedError(dbus.DBusException):
32
" permission denied by policy "
36
class ProxyBackend(dbus.service.Object):
37
DBUS_INTERFACE_NAME = "com.ubuntu.SystemService"
39
SUPPORTED_PROXIES = ("http","ftp", "https", "socks")
42
bus_name = dbus.service.BusName(self.DBUS_INTERFACE_NAME,
44
dbus.service.Object.__init__(self, bus_name, '/')
47
def _authWithPolicyKit(self, sender, connection, priv):
48
#print "_authWithPolicyKit()"
49
system_bus = dbus.SystemBus()
50
obj = system_bus.get_object("org.freedesktop.PolicyKit",
52
"org.freedesktop.PolicyKit")
53
policykit = dbus.Interface(obj, "org.freedesktop.PolicyKit")
54
info = dbus.Interface(connection.get_object('org.freedesktop.DBus',
55
'/org/freedesktop/DBus/Bus',
57
'org.freedesktop.DBus')
58
pid = info.GetConnectionUnixProcessID(sender)
61
# FIXME: not sure what revoke_if_one_shot (last arg) does
62
ok = policykit.IsProcessAuthorized(priv, dbus.UInt32(pid), True)
68
def _etc_environment_proxy(self, proxy_type):
69
" internal that returns the /etc/environment proxy "
70
if not os.path.exists("/etc/environment"):
72
for line in open("/etc/environment"):
73
if line.startswith("%s_proxy=" % proxy_type):
74
(key, value) = line.strip().split("=")
75
value = value.strip('"')
79
def _http_proxy(self):
80
" internal helper that returns the current http proxy "
81
apt_proxy = self._apt_proxy("http")
82
env_proxy = self._etc_environment_proxy("http")
83
# FIXME: what to do if both proxies are differnet?
86
def _apt_proxy(self, proxy_type):
87
" internal helper that returns the configured apt proxy"
89
proxy = apt_pkg.Config.Find("Acquire::%s::proxy" % proxy_type)
93
apt_proxy = self._apt_proxy("ftp")
94
env_proxy = self._etc_environment_proxy("ftp")
95
# FIXME: what to do if both proxies are differnet?
98
def _socks_proxy(self):
99
env_proxy = self._etc_environment_proxy("socks")
102
def _ftp_apt_proxy(self):
103
" internal helper that returns the configured apt proxy"
105
http_proxy = apt_pkg.Config.Find("Acquire::ftp::proxy")
108
def _https_proxy(self):
109
" internal helper that returns the current https proxy "
110
env_proxy = self._etc_environment_proxy("https")
113
def _verify_proxy(self, proxy_type, proxy):
114
" internal helper, verify that the proxy string is valid "
115
return verify_proxy(proxy_type, proxy)
117
def _verify_no_proxy(self, proxy):
118
" internal helper, verify that the no_proxy string is valid "
119
return verify_no_proxy(proxy)
121
@dbus.service.method(DBUS_INTERFACE_NAME,
124
sender_keyword='sender',
125
connection_keyword='conn')
126
def get_proxy(self, proxy_type, sender=None, conn=None):
128
Get the current system-wide proxy for type "proxy_type"
130
This function will look in the apt configuration to
131
find the current http proxy.
133
if proxy_type == "http":
134
return self._http_proxy()
135
if proxy_type == "https":
136
return self._https_proxy()
137
elif proxy_type == "ftp":
138
return self._ftp_proxy()
139
elif proxy_type == "socks":
140
return self._socks_proxy()
141
raise UnknownProxyTypeError, "proxy_type '%s' is unknown in get_proxy" % proxy_type
144
def _write_apt_proxy(self, proxy_type, new_proxy):
145
" helper that writes the new apt proxy "
146
confdir = apt_pkg.Config.FindDir("Dir::Etc")
147
if not self._verify_proxy(proxy_type, new_proxy):
149
# check for the easy case (no proxy setting in the config)
150
old_proxy = self._apt_proxy(proxy_type)
152
f=open(os.path.join(confdir, "apt.conf"),"a")
153
f.write("Acquire::%s::proxy \"%s\";\n" % (proxy_type, new_proxy))
156
# now the difficult case (search the apt configuration files)
157
# build the list of apt configuration files first
158
apt_conffiles = [os.path.join(confdir,"apt.conf.d",n) for n in
159
os.listdir(os.path.join(confdir,"apt.conf.d"))]
160
apt_conffiles.insert(0, os.path.join(confdir,"apt.conf"))
161
# then scan them for the content
162
for f in apt_conffiles:
166
if line.lower().startswith("acquire::%s::proxy" % proxy_type):
168
line = "Acquire::%s::proxy \"%s\";\n" % (proxy_type, new_proxy)
169
# FIXME: scan for more complicated forms of the proxy
170
# settings and/or scan for the proxy string and just
172
new_content.append(line)
173
# if we found/replaced the proxy, write it out now
175
open(f,"w").write("".join(new_content))
179
def _write_etc_environment_proxy(self, proxy_type, new_proxy):
180
if not self._verify_proxy(proxy_type, new_proxy):
184
new_proxy_line = '%s_proxy="%s"\n' % (proxy_type, new_proxy)
185
for line in open("/etc/environment"):
186
if line.startswith("%s_proxy=" % proxy_type):
189
new_content.append(line)
191
open("/etc/environment","w").write("".join(new_content))
193
open("/etc/environment","a").write(new_proxy_line)
196
def _clear_etc_environment_proxy(self, proxy_type):
199
for line in open("/etc/environment"):
200
if line.startswith("%s_proxy=" % proxy_type):
203
new_content.append(line)
205
open("/etc/environment","w").write("".join(new_content))
208
def _clear_apt_proxy(self, proxy_type):
209
" helper that clears the apt proxy "
210
confdir = apt_pkg.Config.FindDir("Dir::Etc")
211
apt_conffiles = [os.path.join(confdir,"apt.conf.d",n) for n in
212
os.listdir(os.path.join(confdir,"apt.conf.d"))]
213
apt_conffiles.insert(0, os.path.join(confdir,"apt.conf"))
214
for f in apt_conffiles:
218
if line.lower().startswith("acquire::%s::proxy" % proxy_type):
221
new_content.append(line)
222
# if we found/replaced the proxy, write it out now
224
open(f,"w").write("".join(new_content))
227
@dbus.service.method(DBUS_INTERFACE_NAME,
230
sender_keyword='sender',
231
connection_keyword='conn')
232
def set_proxy(self, proxy_type, new_proxy, sender=None, conn=None):
234
Set a new system-wide proxy that looks like e.g.:
235
http://proxy.host.net:port/
237
This function will set a new apt configuration and
238
modify /etc/environment
241
if not self._authWithPolicyKit(sender, conn,
242
"com.ubuntu.systemservice.setproxy"):
243
raise PermissionDeniedError, "Permission denied by policy"
245
# check if something supported is set
246
if not proxy_type in self.SUPPORTED_PROXIES:
247
raise UnknownProxyTypeError, "proxy_type '%s' is unknown in set_proxy" % proxy_type
250
if new_proxy == "" or new_proxy is None:
251
res = self._clear_apt_proxy(proxy_type)
252
res &= self._clear_etc_environment_proxy(proxy_type)
254
res = self._write_apt_proxy(proxy_type, new_proxy)
255
res &= self._write_etc_environment_proxy(proxy_type, new_proxy)
259
def _clear_etc_environment_no_proxy(self):
262
for line in open("/etc/environment"):
263
if line.startswith("no_proxy="):
266
new_content.append(line)
268
open("/etc/environment","w").write("".join(new_content))
271
def _write_etc_environment_no_proxy(self, new_proxy):
272
if not self._verify_no_proxy(new_proxy):
276
new_proxy_line = 'no_proxy="%s"\n' % new_proxy
277
for line in open("/etc/environment"):
278
if line.startswith("no_proxy="):
281
new_content.append(line)
283
open("/etc/environment","w").write("".join(new_content))
285
open("/etc/environment","a").write(new_proxy_line)
290
@dbus.service.method(DBUS_INTERFACE_NAME,
293
sender_keyword='sender',
294
connection_keyword='conn')
295
def set_no_proxy(self, new_no_proxy, sender=None, conn=None):
297
Set a new system-wide no_proxy list that looks like e.g.:
300
This function will modify /etc/environment
303
if not self._authWithPolicyKit(sender, conn,
304
"com.ubuntu.systemservice.setnoproxy"):
305
raise PermissionDeniedError, "Permission denied by policy"
308
if new_no_proxy == "" or new_no_proxy is None:
309
res = self._clear_no_proxy()
311
res = self._write_etc_environment_no_proxy(new_no_proxy)
314
if __name__ == "__main__":
315
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
316
server = ProxyBackend()
317
gobject.MainLoop().run()