2
# -*- coding: utf-8 -*-
4
""" wicd - wireless connection daemon implementation.
6
This module implements the wicd daemon that provides network
7
connection management, for both wireless and wired networks. The daemon
8
must be run as root to control the networks, however the user interface
9
components should be run as a normal user.
11
class WicdDaemon() -- DBus interface to manage general wicd processes.
12
class WiredDaemon() -- DBus interface to managed the wired network.
13
class WirelessDaemon() -- DBus interface to managed the wireless network.
18
# Copyright (C) 2007 - 2009 Adam Blackburn
19
# Copyright (C) 2007 - 2009 Dan O'Reilly
20
# Copyright (C) 2007 - 2009 Byron Hillis
21
# Copyright (C) 2009 Andrew Psaltis
23
# This program is free software; you can redistribute it and/or modify
24
# it under the terms of the GNU General Public License Version 2 as
25
# published by the Free Software Foundation.
27
# This program is distributed in the hope that it will be useful,
28
# but WITHOUT ANY WARRANTY; without even the implied warranty of
29
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30
# GNU General Public License for more details.
32
# You should have received a copy of the GNU General Public License
33
# along with this program. If not, see <http://www.gnu.org/licenses/>.
43
from subprocess import Popen
49
if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):
52
from dbus.mainloop.glib import DBusGMainLoop
53
DBusGMainLoop(set_as_default=True)
55
# wicd specific libraries
56
from wicd import wpath
57
from wicd import networking
59
from wicd import wnettools
60
from wicd.misc import noneToBlankString, _status_dict
61
from wicd.logfile import ManagedStdio
62
from wicd.configmanager import ConfigManager
64
if __name__ == '__main__':
67
misc.RenameProcess("wicd")
69
wireless_conf = os.path.join(wpath.etc, "wireless-settings.conf")
70
wired_conf = os.path.join(wpath.etc, "wired-settings.conf")
71
dhclient_conf = os.path.join(wpath.etc, "dhclient.conf.template")
73
class WicdDaemon(dbus.service.Object):
74
""" The main wicd daemon class.
76
This class mostly contains exported DBus methods that are not
77
associated directly with either wired or wireless actions. There
78
are a few exceptions to this, due to architectural limitations.
81
def __init__(self, bus_name, object_path="/org/wicd/daemon",
83
""" Initializes the daemon DBus object. """
84
dbus.service.Object.__init__(self, bus_name=bus_name,
85
object_path=object_path)
86
self.config = ConfigManager(os.path.join(wpath.etc,
87
"manager-settings.conf"))
88
self._debug_mode = bool(self.config.get("Settings", "debug_mode"))
89
self.wifi = networking.Wireless(debug=self._debug_mode)
90
self.wired = networking.Wired(debug=self._debug_mode)
91
self.wired_bus = WiredDaemon(bus_name, self, wired=self.wired)
92
self.wireless_bus = WirelessDaemon(bus_name, self, wifi=self.wifi)
93
self.forced_disconnect = False
94
self.need_profile_chooser = False
95
self.current_interface = None
96
self.vpn_session = None
98
self.suspended = False
99
self._debug_mode = False
100
self.connection_state = misc.NOT_CONNECTED
101
self.connection_info = [""]
102
self.auto_connecting = False
103
self.prefer_wired = False
104
self.show_never_connect = True
106
self.link_detect_tool = 0
110
# This will speed up the scanning process - if a client doesn't
111
# need a fresh scan, just feed them the old one. A fresh scan
112
# can be done by calling Scan(fresh=True).
115
# Load the config file
118
signal.signal(signal.SIGTERM, self.DaemonClosing)
119
self.DaemonStarting()
121
# Scan since we just got started
123
print "--no-autoconnect detected, not autoconnecting..."
124
self.SetForcedDisconnect(True)
125
self.wireless_bus.Scan()
127
def get_debug_mode(self):
128
return self._debug_mode
129
def set_debug_mode(self, mode):
130
self._debug_mode = mode
131
self.config.debug = mode
132
debug_mode = property(get_debug_mode, set_debug_mode)
134
@dbus.service.method('org.wicd.daemon')
136
""" Returns the version number.
138
This number is major-minor-micro. Major is only incremented if minor
139
reaches > 9. Minor is incremented if changes that break core stucture
140
are implemented. Micro is for everything else, and micro may be
141
anything >= 0. This number is effective starting wicd v1.2.0.
146
@dbus.service.method('org.wicd.daemon')
147
def SetWiredInterface(self, interface):
148
""" Sets the wired interface for the daemon to use. """
149
print "setting wired interface %s" % (str(interface))
150
self.wired.wired_interface = noneToBlankString(interface)
151
self.config.set("Settings", "wired_interface", interface, write=True)
153
@dbus.service.method('org.wicd.daemon')
154
def SetWirelessInterface(self, interface):
155
""" Sets the wireless interface the daemon will use. """
156
print "setting wireless interface %s" % (str(interface))
157
self.wifi.wireless_interface = noneToBlankString(interface)
158
self.config.set("Settings", "wireless_interface", interface, write=True)
160
@dbus.service.method('org.wicd.daemon')
161
def SetWPADriver(self, driver):
162
""" Sets the wpa driver the wpa_supplicant will use. """
163
print "setting wpa driver", str(driver)
164
self.wifi.wpa_driver = driver
165
self.config.set("Settings", "wpa_driver", driver, write=True)
167
@dbus.service.method('org.wicd.daemon')
168
def SetUseGlobalDNS(self, use):
169
""" Sets a boolean which determines if global DNS is enabled. """
170
print 'setting use global dns to', use
171
use = misc.to_bool(use)
172
self.config.set("Settings", "use_global_dns", use, write=True)
173
self.use_global_dns = use
174
self.wifi.use_global_dns = use
175
self.wired.use_global_dns = use
177
@dbus.service.method('org.wicd.daemon')
178
def SetGlobalDNS(self, dns1=None, dns2=None, dns3=None,
179
dns_dom =None, search_dom=None):
180
""" Sets the global dns addresses. """
181
print "setting global dns"
182
self.config.set("Settings", "global_dns_1", misc.noneToString(dns1))
184
self.wifi.global_dns_1 = dns1
185
self.wired.global_dns_1 = dns1
186
self.config.set("Settings", "global_dns_2", misc.noneToString(dns2))
188
self.wifi.global_dns_2 = dns2
189
self.wired.global_dns_2 = dns2
190
self.config.set("Settings", "global_dns_3", misc.noneToString(dns3))
192
self.wifi.global_dns_3 = dns3
193
self.wired.global_dns_3 = dns3
194
self.config.set("Settings", "global_dns_dom", misc.noneToString(dns_dom))
195
self.dns_dom = dns_dom
196
self.wifi.dns_dom = dns_dom
197
self.wired.dns_dom = dns_dom
198
self.config.set("Settings", "global_search_dom", misc.noneToString(search_dom))
199
self.search_dom = search_dom
200
self.wifi.global_search_dom = search_dom
201
self.wired.global_search_dom = search_dom
202
print 'global dns servers are', dns1, dns2, dns3
203
print 'domain is %s' % dns_dom
204
print 'search domain is %s' % search_dom
207
@dbus.service.method('org.wicd.daemon')
208
def SetBackend(self, backend):
209
""" Sets a new backend. """
210
print "setting backend to %s" % backend
211
backends = networking.BACKEND_MGR.get_available_backends()
212
if backend not in backends:
213
print "backend %s not available, trying to fallback to another" % backend
215
backend = backends[0]
217
print "ERROR: no backends available!"
220
print "Fell back to backend %s" % backend
221
self.config.set("Settings", "backend", backend, write=True)
222
if backend != self.GetCurrentBackend():
223
self.suspended = True
224
self.wifi.LoadBackend(backend)
225
self.wired.LoadBackend(backend)
226
self.SignalBackendChanged(self.GetBackendUpdateInterval())
227
self.SetSuspend(False)
229
@dbus.service.method('org.wicd.daemon')
230
def GetCurrentBackend(self):
231
""" Returns the currently loaded backend. """
232
return networking.get_current_backend()
234
@dbus.service.method('org.wicd.daemon')
235
def GetBackendUpdateInterval(self):
236
""" Returns status update interval for the loaded backend. """
237
return networking.get_backend_update_interval()
239
@dbus.service.method('org.wicd.daemon')
240
def GetBackendDescription(self, backend_name):
241
""" Returns the description of the given backend. """
242
return networking.get_backend_description(backend_name)
244
@dbus.service.method('org.wicd.daemon')
245
def GetBackendDescriptionDict(self):
246
""" Returns a dict of all backend names mapped to their description. """
247
return networking.get_backend_description_dict()
249
@dbus.service.method('org.wicd.daemon')
250
def GetSavedBackend(self):
251
""" Returns the backend saved to disk. """
252
return self.config.get("Settings", "backend")
254
@dbus.service.method('org.wicd.daemon')
255
def GetBackendList(self):
256
""" Returns a list of all backends available. """
257
return networking.get_backend_list()
259
@dbus.service.method('org.wicd.daemon')
260
def GetUseGlobalDNS(self):
261
""" Returns a boolean that determines if global dns is enabled. """
262
return bool(self.use_global_dns)
264
@dbus.service.method('org.wicd.daemon')
265
def GetWPADriver(self):
266
""" Returns the wpa driver the daemon is using. """
267
return str(self.wifi.wpa_driver)
269
@dbus.service.method('org.wicd.daemon')
270
def GetWiredInterface(self):
271
""" Returns the wired interface. """
272
return str(self.wired.wired_interface)
274
@dbus.service.method('org.wicd.daemon')
275
def GetWirelessInterface(self):
276
""" Returns the wireless interface the daemon is using. """
277
return str(self.wifi.wireless_interface)
279
@dbus.service.method('org.wicd.daemon')
280
def NeedsExternalCalls(self):
281
""" Returns true if the loaded backend needs external calls. """
283
return self.wifi.NeedsExternalCalls()
285
return self.wired.NeedsExternalCalls()
289
@dbus.service.method('org.wicd.daemon')
290
def SetDebugMode(self, debug):
291
""" Sets if debugging mode is on or off. """
292
self.config.set("Settings", "debug_mode", debug, write=True)
293
self.debug_mode = misc.to_bool(debug)
294
self.wifi.debug = debug
295
self.wired.debug = debug
296
self.wireless_bus.debug_mode = debug
297
self.wired_bus.debug_mode = debug
299
@dbus.service.method('org.wicd.daemon')
300
def GetDebugMode(self):
301
""" Returns whether debugging is enabled. """
302
return bool(self.debug_mode)
304
@dbus.service.method('org.wicd.daemon')
305
def Disconnect(self):
306
""" Disconnects all networks. """
307
self.SetForcedDisconnect(True)
308
self.wifi.Disconnect()
309
self.wired.Disconnect()
311
@dbus.service.method('org.wicd.daemon')
312
def FormatSignalForPrinting(self, signal):
313
""" Returns the suffix to display after the signal strength number. """
314
if self.GetSignalDisplayType() == 1:
315
return '%s dBm' % signal
318
if int(signal) == 101:
321
return '%s%%' % signal
323
return '%s%%' % signal
325
@dbus.service.method('org.wicd.daemon')
326
def SetSuspend(self, val):
327
""" Toggles whether or not monitoring connection status is suspended """
332
self.SetForcedDisconnect(False)
334
@dbus.service.method('org.wicd.daemon')
335
def GetSuspend(self):
336
""" Returns True if the computer is in the suspend state. """
337
return self.suspended
339
@dbus.service.method('org.wicd.daemon')
340
def AutoConnect(self, fresh):
341
""" Attempts to autoconnect to a wired or wireless network.
343
Autoconnect will first try to connect to a wired network, if that
344
fails it tries a wireless connection.
347
print "Autoconnecting..."
348
if self.CheckIfConnecting():
350
print 'Already connecting, doing nothing.'
352
# We don't want to rescan/connect if the gui is open.
355
print "Skipping autoconnect because GUI is open."
357
if self.wired_bus.CheckPluggedIn():
359
print "Starting wired autoconnect..."
360
self._wired_autoconnect(fresh)
363
print "Starting wireless autoconnect..."
364
self.wireless_bus._wireless_autoconnect(fresh)
366
@dbus.service.method('org.wicd.daemon')
367
def GetAutoReconnect(self):
368
""" Returns the value of self.auto_reconnect. See SetAutoReconnect. """
369
return bool(self.auto_reconnect)
371
@dbus.service.method('org.wicd.daemon')
372
def SetAutoReconnect(self, value):
373
""" Sets the value of self.auto_reconnect.
375
If True, wicd will try to reconnect as soon as it detects that
376
an internet connection is lost. If False, it will do nothing,
377
and wait for the user to initiate reconnection.
380
print 'setting automatically reconnect when connection drops %s' % value
381
self.config.set("Settings", "auto_reconnect", misc.to_bool(value),
383
self.auto_reconnect = misc.to_bool(value)
385
@dbus.service.method('org.wicd.daemon')
386
def GetGlobalDNSAddresses(self):
387
""" Returns the global dns addresses. """
388
return (misc.noneToString(self.dns1), misc.noneToString(self.dns2),
389
misc.noneToString(self.dns3), misc.noneToString(self.dns_dom),
390
misc.noneToString(self.search_dom))
392
@dbus.service.method('org.wicd.daemon')
393
def CheckIfConnecting(self):
394
""" Returns if a network connection is being made. """
395
if self.wired_bus.CheckIfWiredConnecting() or \
396
self.wireless_bus.CheckIfWirelessConnecting():
401
@dbus.service.method('org.wicd.daemon')
402
def CancelConnect(self):
403
""" Cancels the wireless connection attempt """
404
print 'canceling connection attempt'
405
if self.wifi.connecting_thread:
406
self.wifi.connecting_thread.should_die = True
407
self.wifi.ReleaseDHCP()
408
# We have to actually kill dhcp if its still hanging
409
# around. It could still be trying to get a lease.
412
self.wifi.connecting_thread.connect_result = 'aborted'
413
if self.wired.connecting_thread:
414
self.wired.connecting_thread.should_die = True
415
self.wired.ReleaseDHCP()
416
self.wired.KillDHCP()
417
self.wired.connecting_thread.connect_result = 'aborted'
419
@dbus.service.method('org.wicd.daemon')
420
def GetCurrentInterface(self):
421
""" Returns the active interface """
422
return self.current_interface
424
@dbus.service.method('org.wicd.daemon')
425
def SetCurrentInterface(self, iface):
426
""" Sets the current active interface """
427
self.current_interface = str(iface)
429
@dbus.service.method('org.wicd.daemon')
430
def SetNeedWiredProfileChooser(self, val):
431
""" Sets the need_wired_profile_chooser variable.
433
If set to True, that alerts the wicd frontend to display the chooser,
434
if False the frontend will do nothing. This function is only needed
435
when the frontend starts up, to determine if the chooser was requested
436
before the frontend was launched.
439
self.need_profile_chooser = misc.to_bool(val)
441
@dbus.service.method('org.wicd.daemon')
442
def ShouldAutoReconnect(self):
443
""" Returns True if it's the right time to try autoreconnecting. """
444
if self.GetAutoReconnect() and not self.CheckIfConnecting() and \
445
not self.GetForcedDisconnect() and not self.auto_connecting and \
451
@dbus.service.method('org.wicd.daemon')
452
def GetForcedDisconnect(self):
453
""" Returns the forced_disconnect status. See SetForcedDisconnect. """
454
return bool(self.forced_disconnect)
456
@dbus.service.method('org.wicd.daemon')
457
def SetForcedDisconnect(self, value):
458
""" Sets the forced_disconnect status.
460
Set to True when a user manually disconnects or cancels a connection.
461
It gets set to False as soon as the connection process is manually
465
if self.debug_mode and value: print "Forced disconnect on"
466
self.forced_disconnect = bool(value)
468
@dbus.service.method('org.wicd.daemon')
469
def GetSignalDisplayType(self):
470
""" Returns the signal display type.
472
Returns either 0 or 1.
473
0 for signal strength as a percentage
474
1 for signal strength measured in dBm
477
return int(self.signal_display_type)
479
@dbus.service.method('org.wicd.daemon')
480
def SetSignalDisplayType(self, value):
481
""" Sets the signal display type and writes it the wicd config file. """
482
self.config.set("Settings", "signal_display_type", value, write=True)
483
self.signal_display_type = int(value)
485
@dbus.service.method('org.wicd.daemon')
486
def GetGUIOpen(self):
487
""" Returns the value of gui_open.
489
Returns the vlaue of gui_open, which is a boolean that keeps track
490
of the state of the wicd GUI. If the GUI is open, wicd will not
491
try to automatically reconnect to networks, as this behavior can
492
be annoying for the user while trying to use the GUI.
494
NOTE: It's possible for this to become out of sync, particularly if
495
the wicd.py is not exited properly while the GUI is open. We should
496
probably implement some kind of pid system to do it properly.
498
ANOTHER NOTE: This isn't used by anything yet!
501
return bool(self.gui_open)
503
@dbus.service.method('org.wicd.daemon')
504
def SetGUIOpen(self, val):
505
""" Sets the value of gui_open. """
506
self.gui_open = bool(val)
508
@dbus.service.method('org.wicd.daemon')
509
def SetAlwaysShowWiredInterface(self, value):
510
""" Sets always_show_wired_interface to the given value. """
511
self.config.set("Settings", "always_show_wired_interface",
512
misc.to_bool(value), write=True)
513
self.always_show_wired_interface = misc.to_bool(value)
515
@dbus.service.method('org.wicd.daemon')
516
def GetAlwaysShowWiredInterface(self):
517
""" Returns always_show_wired_interface """
518
return bool(self.always_show_wired_interface)
520
@dbus.service.method('org.wicd.daemon')
521
def SetWiredAutoConnectMethod(self, method):
522
""" Sets which method to use to autoconnect to wired networks. """
523
# 1 = default profile
525
# 3 = last used profile
526
self.config.set("Settings", "wired_connect_mode", int(method),
528
self.wired_connect_mode = int(method)
529
self.wired_bus.connect_mode = int(method)
531
@dbus.service.method('org.wicd.daemon')
532
def SetShouldVerifyAp(self, value):
533
""" Enable/disable wireless AP verification.
535
If this is True, wicd will try to verify that we are associated
536
with the Wireless AP after a connection attempt appears to
540
self.config.set("Settings", "should_verify_ap", int(value), write=True)
541
self.wifi.should_verify_ap = misc.to_bool(value)
543
@dbus.service.method('org.wicd.daemon')
544
def GetShouldVerifyAp(self):
545
""" Returns current value for WAP connection verification. """
546
return bool(self.wifi.should_verify_ap)
548
@dbus.service.method('org.wicd.daemon')
549
def GetWiredAutoConnectMethod(self):
550
""" Returns the wired autoconnect method. """
551
return int(self.wired_connect_mode)
553
@dbus.service.method('org.wicd.daemon')
554
def GetPreferWiredNetwork(self):
555
""" Returns True if wired network preference is set.
557
If this is True, wicd will switch from a wireless connection
558
to a wired one if an ethernet connection is available.
561
return self.prefer_wired
563
@dbus.service.method('org.wicd.daemon')
564
def SetPreferWiredNetwork(self, value):
565
""" Sets the prefer_wired state. """
566
self.config.set("Settings", "prefer_wired", bool(value), write=True)
567
self.prefer_wired = bool(value)
569
@dbus.service.method('org.wicd.daemon')
570
def GetShowNeverConnect(self):
571
""" Returns True if show_never_connect is set
573
if True then the client will show networks marked as never connect
575
return self.show_never_connect
577
@dbus.service.method('org.wicd.daemon')
578
def SetShowNeverConnect(self, value):
579
""" Sets the how_never_connect state. """
580
self.config.set("Settings", "show_never_connect", bool(value), write=True)
581
self.show_never_connect = bool(value)
583
@dbus.service.method('org.wicd.daemon')
584
def SetConnectionStatus(self, state, info):
585
""" Sets the connection status.
588
state - An int representing the state of the connection as defined
591
info - a list of strings containing data about the connection state.
592
The contents of this list are dependent on the connection state.
594
state - info contents:
595
NOT_CONNECTED - info[0] = ""
596
CONNECTING - info[0] = "wired" or "wireless"
597
info[1] = None if wired, an essid if wireless
598
WIRED - info[0] = IP Adresss
599
WIRELESS - info[0] = IP Address
601
info[2] = signal strength
602
info[3] = internal networkid
604
SUSPENDED - info[0] = ""
608
self.connection_state = state
609
self.connection_info = info
611
@dbus.service.method('org.wicd.daemon', out_signature='(uas)')
612
def GetConnectionStatus(self):
613
""" Returns the current connection state in list form.
615
See SetConnectionStatus for more information about the
616
data structure being returned.
619
return [self.connection_state, self.connection_info]
621
@dbus.service.method('org.wicd.daemon')
622
def GetNeedWiredProfileChooser(self):
623
""" Returns need_profile_chooser.
625
Returns a boolean specifying if the wired profile chooser needs to
629
return bool(self.need_profile_chooser)
631
@dbus.service.method("org.wicd.daemon")
632
def GetAppAvailable(self, app):
633
""" Determine if a given application is available."""
634
return bool(self.wifi.AppAvailable(app) or self.wired.AppAvailable(app))
636
@dbus.service.method('org.wicd.daemon')
637
def GetDHCPClient(self):
638
""" Returns the current DHCP client constant.
640
See misc.py for a definition of the constants.
643
return self.dhcp_client
645
@dbus.service.method('org.wicd.daemon')
646
def SetDHCPClient(self, client):
647
""" Sets the DHCP client constant.
649
See misc.py for a definition of the constants.
652
print "Setting dhcp client to %i" % (int(client))
653
self.dhcp_client = int(client)
654
self.wifi.dhcp_client = int(client)
655
self.wired.dhcp_client = int(client)
656
self.config.set("Settings", "dhcp_client", client, write=True)
658
@dbus.service.method('org.wicd.daemon')
659
def GetLinkDetectionTool(self):
660
""" Returns the current link detection tool constant. """
661
return self.link_detect_tool
663
@dbus.service.method('org.wicd.daemon')
664
def SetLinkDetectionTool(self, link_tool):
665
""" Sets the link detection tool.
667
Sets the value of the tool wicd should use to detect if a
668
cable is plugged in. If using a backend that doesn't use
669
an external call to get this information (such as ioctl)
670
it will instead use the ioctls provided by the specified
671
tool to query for link status.
674
self.link_detect_tool = int(link_tool)
675
self.wired.link_detect = int(link_tool)
676
self.config.set("Settings", "link_detect_tool", link_tool, write=True)
678
@dbus.service.method('org.wicd.daemon')
679
def GetFlushTool(self):
680
""" Returns the current flush tool constant. """
681
return self.flush_tool
683
@dbus.service.method('org.wicd.daemon')
684
def SetFlushTool(self, flush_tool):
685
""" Sets the flush tool.
687
Sets the value of the tool wicd should use to flush routing tables.
688
The value is associated with a particular tool, as specified in
692
self.flush_tool = int(flush_tool)
693
self.wired.flush_tool = int(flush_tool)
694
self.wifi.flush_tool = int(flush_tool)
695
self.config.set("Settings", "flush_tool", flush_tool, write=True)
697
@dbus.service.method('org.wicd.daemon')
698
def GetSudoApp(self):
699
""" Get the preferred sudo app. """
702
@dbus.service.method('org.wicd.daemon')
703
def SetSudoApp(self, sudo_app):
704
""" Set the preferred sudo app. """
705
self.sudo_app = sudo_app
706
self.config.set("Settings", "sudo_app", sudo_app, write=True)
708
def _wired_autoconnect(self, fresh=True):
709
""" Attempts to autoconnect to a wired network. """
710
wiredb = self.wired_bus
711
if self.GetWiredAutoConnectMethod() == 3 and \
712
not self.GetNeedWiredProfileChooser():
713
# attempt to smartly connect to a wired network
714
# by using various wireless networks detected
715
# and by using plugged in USB devices
717
if self.GetWiredAutoConnectMethod() == 2 and \
718
not self.GetNeedWiredProfileChooser():
723
elif self.GetWiredAutoConnectMethod() == 1:
724
network = wiredb.GetDefaultWiredNetwork()
726
print "Couldn't find a default wired connection," + \
727
" wired autoconnect failed."
728
self.wireless_bus._wireless_autoconnect(fresh)
733
network = wiredb.GetLastUsedWiredNetwork()
735
print "no previous wired profile available, wired " + \
736
"autoconnect failed."
737
self.wireless_bus._wireless_autoconnect(fresh)
740
wiredb.ReadWiredNetworkProfile(network)
741
wiredb.ConnectWired()
742
print "Attempting to autoconnect with wired interface..."
743
self.auto_connecting = True
746
gobject.timeout_add_seconds(3, self._monitor_wired_autoconnect,
749
gobject.timeout_add(3000, self._monitor_wired_autoconnect, fresh)
752
def _monitor_wired_autoconnect(self, fresh):
753
""" Monitor a wired auto-connection attempt.
755
Helper method called on a timer that monitors a wired
756
connection attempt and makes decisions about what to
757
do next based on the result.
760
wiredb = self.wired_bus
761
if wiredb.CheckIfWiredConnecting():
763
elif wiredb.GetWiredIP():
764
self.auto_connecting = False
766
elif not self.wireless_bus.CheckIfWirelessConnecting():
767
self.wireless_bus._wireless_autoconnect(fresh)
769
self.auto_connecting = False
772
@dbus.service.method("org.wicd.daemon")
773
def ConnectResultsAvailable(self):
774
if ((self.wired.connecting_thread and self.wired.connecting_thread.connect_result) or
775
(self.wifi.connecting_thread and self.wifi.connecting_thread.connect_result)):
780
@dbus.service.method("org.wicd.daemon")
781
def SendConnectResultsIfAvail(self):
782
if self.ConnectResultsAvailable():
783
self.SendConnectResult()
785
@dbus.service.method("org.wicd.daemon")
786
def SendConnectResult(self):
787
if self.wired.connecting_thread and self.wired.connecting_thread.connect_result:
788
self.ConnectResultsSent(self.wired.connecting_thread.connect_result)
789
self.wired.connecting_thread.connect_result = ""
790
elif self.wifi.connecting_thread and self.wifi.connecting_thread.connect_result:
791
self.ConnectResultsSent(self.wifi.connecting_thread.connect_result)
792
self.wifi.connecting_thread.connect_result = ""
794
@dbus.service.signal(dbus_interface="org.wicd.daemon",signature='s')
795
def ConnectResultsSent(self, result):
796
print "Sending connection attempt result %s" % result
798
@dbus.service.method("org.wicd.daemon")
799
@dbus.service.signal(dbus_interface="org.wicd.daemon", signature='')
800
def UpdateState(self):
803
@dbus.service.signal(dbus_interface='org.wicd.daemon', signature='')
804
def LaunchChooser(self):
805
""" Emits the wired profile chooser dbus signal. """
806
print 'calling wired profile chooser'
807
self.SetNeedWiredProfileChooser(True)
809
@dbus.service.signal(dbus_interface="org.wicd.daemon", signature='')
810
def DaemonStarting(self):
811
""" Emits a signa indicating the daemon is starting. """
814
@dbus.service.signal(dbus_interface='org.wicd.daemon', signature='')
815
def DaemonClosing(self):
816
""" Emits a signal indicating the daemon will be closing. """
819
@dbus.service.method('org.wicd.daemon', in_signature='uav')
820
def EmitStatusChanged(self, state, info):
821
""" Calls the StatusChanged signal method. """
822
self.StatusChanged(state, info)
824
@dbus.service.signal(dbus_interface='org.wicd.daemon', signature='uav')
825
def StatusChanged(self, state, info):
826
""" Emits a "status changed" dbus signal.
828
This D-Bus signal is emitted when the connection status changes.
829
This signal can be hooked to monitor the network state.
834
@dbus.service.signal(dbus_interface='org.wicd.daemon', signature='i')
835
def SignalBackendChanged(self, interval):
836
""" Emits a signal when the current backend changes. """
839
def ReadConfig(self):
840
""" Reads the manager-settings.conf file.
842
Reads the manager-settings.conf file and loads the stored
846
b_wired = self.wired_bus
847
b_wifi = self.wireless_bus
848
app_conf = self.config
851
self.SetBackend(app_conf.get("Settings", "backend", default=be_def))
853
# Load network interfaces.
854
iface = self.wireless_bus.DetectWirelessInterface()
855
if not iface: iface = 'wlan0'
856
self.SetWirelessInterface(app_conf.get("Settings", "wireless_interface",
858
iface = self.wired_bus.DetectWiredInterface()
859
if not iface: iface = 'eth0'
860
self.SetWiredInterface(app_conf.get("Settings", "wired_interface",
863
self.SetWPADriver(app_conf.get("Settings", "wpa_driver", default="wext"))
864
self.SetAlwaysShowWiredInterface(app_conf.get("Settings",
865
"always_show_wired_interface",
867
self.SetUseGlobalDNS(app_conf.get("Settings", "use_global_dns",
869
dns1 = app_conf.get("Settings", "global_dns_1", default='None')
870
dns2 = app_conf.get("Settings", "global_dns_2", default='None')
871
dns3 = app_conf.get("Settings", "global_dns_3", default='None')
872
dns_dom = app_conf.get("Settings", "global_dns_dom", default='None')
873
search_dom = app_conf.get("Settings", "global_search_dom", default='None')
874
self.SetGlobalDNS(dns1, dns2, dns3, dns_dom, search_dom)
875
self.SetAutoReconnect(app_conf.get("Settings", "auto_reconnect",
877
self.SetDebugMode(app_conf.get("Settings", "debug_mode", default=False))
878
self.SetWiredAutoConnectMethod(app_conf.get("Settings",
879
"wired_connect_mode",
881
self.SetSignalDisplayType(app_conf.get("Settings",
882
"signal_display_type",
884
self.SetShouldVerifyAp(app_conf.get("Settings", "should_verify_ap",
886
self.SetDHCPClient(app_conf.get("Settings", "dhcp_client", default=0))
887
self.SetLinkDetectionTool(app_conf.get("Settings", "link_detect_tool",
889
self.SetFlushTool(app_conf.get("Settings", "flush_tool", default=0))
890
self.SetSudoApp(app_conf.get("Settings", "sudo_app", default=0))
891
self.SetPreferWiredNetwork(app_conf.get("Settings", "prefer_wired",
893
self.SetShowNeverConnect(app_conf.get("Settings", "show_never_connect",
897
if os.path.isfile(wireless_conf):
898
print "Wireless configuration file found..."
900
print "Wireless configuration file not found, creating..."
901
open(wireless_conf, "w").close()
903
if os.path.isfile(wired_conf):
904
print "Wired configuration file found..."
906
print "Wired configuration file not found, creating a default..."
907
# Create the file and a default profile
908
open(wired_conf, "w").close()
909
b_wired.CreateWiredNetworkProfile("wired-default", default=True)
911
if not os.path.isfile(dhclient_conf):
912
print "dhclient.conf.template not found, copying..."
913
shutil.copy(dhclient_conf + ".default", dhclient_conf)
914
# Hide the files, so the keys aren't exposed.
915
print "chmoding configuration files 0600..."
916
os.chmod(app_conf.get_config(), 0600)
917
os.chmod(wireless_conf, 0600)
918
os.chmod(wired_conf, 0600)
919
os.chmod(dhclient_conf, 0644)
922
print "chowning configuration files root:root..."
923
os.chown(app_conf.get_config(), 0, 0)
924
os.chown(wireless_conf, 0, 0)
925
os.chown(wired_conf, 0, 0)
926
os.chown(dhclient_conf, 0, 0)
928
print "Using wireless interface..." + self.GetWirelessInterface()
929
print "Using wired interface..." + self.GetWiredInterface()
931
##############################
932
###### Wireless Daemon #######
933
##############################
935
class WirelessDaemon(dbus.service.Object):
936
""" DBus interface for wireless connection operations. """
937
def __init__(self, bus_name, daemon, wifi=None, debug=False):
938
""" Intitialize the wireless DBus interface. """
939
dbus.service.Object.__init__(self, bus_name=bus_name,
940
object_path='/org/wicd/daemon/wireless')
941
self.hidden_essid = None
944
self._debug_mode = debug
945
self._scanning = False
947
self.config = ConfigManager(wireless_conf, debug=debug)
949
def get_debug_mode(self):
950
return self._debug_mode
951
def set_debug_mode(self, mode):
952
self._debug_mode = mode
953
self.config.debug = mode
954
debug_mode = property(get_debug_mode, set_debug_mode)
956
@dbus.service.method('org.wicd.daemon.wireless')
957
def SetHiddenNetworkESSID(self, essid):
958
""" Sets the ESSID of a hidden network for use with Scan(). """
959
self.hidden_essid = str(misc.Noneify(essid))
961
@dbus.service.method('org.wicd.daemon.wireless')
962
def Scan(self, sync=False):
963
""" Scan for wireless networks.
965
Scans for wireless networks, optionally using a (hidden) essid
966
set with SetHiddenNetworkESSID.
968
The sync keyword argument specifies whether the scan should
969
be done synchronously.
974
print "scan already in progress, skipping"
977
print 'scanning start'
978
self.SendStartScanSignal()
986
def _async_scan(self):
987
""" Run a scan in its own thread. """
990
def _sync_scan(self):
991
""" Run a scan and send a signal when its finished. """
992
scan = self.wifi.Scan(str(self.hidden_essid))
995
print 'scanning done'
996
print 'found ' + str(len(scan)) + ' networks:'
997
for i, network in enumerate(scan):
998
self.ReadWirelessNetworkProfile(i)
999
self.SendEndScanSignal()
1001
@dbus.service.method('org.wicd.daemon.wireless')
1002
def GetIwconfig(self):
1003
""" Calls and returns the output of iwconfig"""
1004
return misc.to_unicode(self.wifi.GetIwconfig())
1006
@dbus.service.method('org.wicd.daemon.wireless')
1007
def GetNumberOfNetworks(self):
1008
""" Returns number of networks. """
1009
return len(self.LastScan)
1011
@dbus.service.method('org.wicd.daemon.wireless')
1012
def GetApBssid(self):
1013
""" Gets the MAC address for the active network. """
1014
return self.wifi.GetBSSID()
1016
@dbus.service.method('org.wicd.daemon.wireless')
1017
def GetCurrentBitrate(self, iwconfig):
1018
""" Returns the current bitrate for the active network. """
1019
return self.wifi.GetCurrentBitrate(iwconfig)
1021
@dbus.service.method('org.wicd.daemon.wireless')
1022
def GetOperationalMode(self, iwconfig):
1023
""" Returns the operational mode for the iwconfig parameter """
1024
return misc.to_unicode(self.wifi.GetOperationalMode(iwconfig))
1026
@dbus.service.method('org.wicd.daemon.wireless')
1027
def GetAvailableAuthMethods(self, iwlistauth):
1028
""" Returns the operational mode for the iwlistauth parameter """
1029
return misc.to_unicode(self.wifi.GetAvailableAuthMethods(iwlistauth))
1031
@dbus.service.method('org.wicd.daemon.wireless')
1032
def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, encused,
1034
""" Creates an ad-hoc network using user inputted settings. """
1035
self.wifi.CreateAdHocNetwork(essid, channel, ip, enctype, key, encused)
1037
@dbus.service.method('org.wicd.daemon.wireless')
1038
def GetKillSwitchEnabled(self):
1039
""" Returns true if kill switch is pressed. """
1040
status = self.wifi.GetKillSwitchStatus()
1043
@dbus.service.method('org.wicd.daemon.wireless')
1044
def SwitchRfKill(self):
1045
""" Switches the rfkill on/off for wireless cards. """
1046
return self.wifi.SwitchRfKill()
1048
@dbus.service.method('org.wicd.daemon.wireless')
1049
def GetRfKillEnabled(self):
1050
""" Returns true if rfkill switch is enabled. """
1051
return self.wifi.GetRfKillStatus()
1053
@dbus.service.method('org.wicd.daemon.wireless')
1054
def GetWirelessProperty(self, networkid, property):
1055
""" Retrieves wireless property from the network specified """
1057
value = self.LastScan[networkid].get(property)
1060
value = misc.to_unicode(value)
1063
@dbus.service.method('org.wicd.daemon.wireless')
1064
def SetWirelessProperty(self, netid, prop, value):
1065
""" Sets property to value in network specified. """
1066
# We don't write script settings here.
1067
prop = misc.sanitize_config(prop)
1068
if prop.endswith('script'):
1069
print 'Setting script properties through the daemon' \
1070
+ ' is not permitted.'
1072
self.LastScan[netid][prop] = misc.to_unicode(misc.Noneify(value))
1074
@dbus.service.method('org.wicd.daemon.wireless')
1075
def DetectWirelessInterface(self):
1076
""" Returns an automatically detected wireless interface. """
1077
iface = self.wifi.DetectWirelessInterface()
1079
print 'Automatically detected wireless interface ' + iface
1081
print "Couldn't detect a wireless interface."
1084
@dbus.service.method('org.wicd.daemon.wireless')
1085
def DisconnectWireless(self):
1086
""" Disconnects the wireless network. """
1087
self.wifi.Disconnect()
1088
self.daemon.UpdateState()
1090
@dbus.service.method('org.wicd.daemon.wireless')
1091
def IsWirelessUp(self):
1092
""" Returns a boolean specifying if wireless is up or down. """
1093
return self.wifi.IsUp()
1095
@dbus.service.method('org.wicd.daemon.wireless')
1096
def GetCurrentSignalStrength(self, iwconfig=None):
1097
""" Returns the current signal strength. """
1099
strength = int(self.wifi.GetSignalStrength(iwconfig))
1104
@dbus.service.method('org.wicd.daemon.wireless')
1105
def GetCurrentDBMStrength(self, iwconfig=None):
1106
""" Returns the current dbm signal strength. """
1108
dbm_strength = int(self.wifi.GetDBMStrength(iwconfig))
1113
@dbus.service.method('org.wicd.daemon.wireless')
1114
def GetCurrentNetwork(self, iwconfig=None):
1115
""" Returns the current network. """
1116
current_network = str(self.wifi.GetCurrentNetwork(iwconfig))
1117
return current_network
1119
@dbus.service.method('org.wicd.daemon.wireless')
1120
def GetCurrentNetworkID(self, iwconfig=None):
1121
""" Returns the id of the current network, or -1 if its not found. """
1122
currentESSID = self.GetCurrentNetwork(iwconfig)
1123
for x in xrange(0, len(self.LastScan)):
1124
if self.LastScan[x]['essid'] == currentESSID:
1127
print 'GetCurrentNetworkID: Returning -1, current network not found'
1130
@dbus.service.method('org.wicd.daemon.wireless')
1131
def EnableWirelessInterface(self):
1132
""" Calls a method to enable the wireless interface. """
1133
result = self.wifi.EnableInterface()
1136
@dbus.service.method('org.wicd.daemon.wireless')
1137
def DisableWirelessInterface(self):
1138
""" Calls a method to disable the wireless interface. """
1139
result = self.wifi.DisableInterface()
1142
@dbus.service.method('org.wicd.daemon.wireless')
1143
def ConnectWireless(self, id):
1144
""" Connects the the wireless network specified by i"""
1145
self.SaveWirelessNetworkProfile(id)
1146
# Will returned instantly, that way we don't hold up dbus.
1147
# CheckIfWirelessConnecting can be used to test if the connection
1149
self.wifi.before_script = self.GetWirelessProperty(id, 'beforescript')
1150
self.wifi.after_script = self.GetWirelessProperty(id, 'afterscript')
1151
self.wifi.pre_disconnect_script = self.GetWirelessProperty(id,
1152
'predisconnectscript')
1153
self.wifi.post_disconnect_script = self.GetWirelessProperty(id,
1154
'postdisconnectscript')
1155
print 'Connecting to wireless network ' + str(self.LastScan[id]['essid'])
1156
# disconnect to make sure that scripts are run
1157
self.wifi.Disconnect()
1158
self.daemon.wired_bus.wired.Disconnect()
1159
self.daemon.SetForcedDisconnect(False)
1160
conthread = self.wifi.Connect(self.LastScan[id], debug=self.debug_mode)
1161
self.daemon.UpdateState()
1163
@dbus.service.method('org.wicd.daemon.wireless')
1164
def CheckIfWirelessConnecting(self):
1165
"""Returns True if wireless interface is connecting, otherwise False."""
1166
if self.wifi.connecting_thread:
1167
return self.wifi.connecting_thread.is_connecting
1171
@dbus.service.method('org.wicd.daemon.wireless')
1172
def GetWirelessIP(self, ifconfig=""):
1173
""" Returns the IP associated with the wireless interface. """
1174
ip = self.wifi.GetIP(ifconfig)
1177
@dbus.service.method('org.wicd.daemon.wireless')
1178
def CheckWirelessConnectingStatus(self):
1179
""" Returns the wireless interface's status code. """
1180
if self.wifi.connecting_thread:
1181
stat = self.wifi.connecting_thread.GetStatus()
1186
@dbus.service.method('org.wicd.daemon.wireless')
1187
def CheckWirelessConnectingMessage(self):
1188
""" Returns the wireless interface's status message. """
1189
if self.wifi.connecting_thread:
1190
stat = self.CheckWirelessConnectingStatus()
1191
return _status_dict[stat]
1195
@dbus.service.method('org.wicd.daemon.wireless')
1196
def ReadWirelessNetworkProfile(self, id):
1197
""" Reads in wireless profile as the active network """
1198
cur_network = self.LastScan[id]
1199
essid_key = "essid:%s" % cur_network["essid"]
1200
bssid_key = cur_network["bssid"]
1202
if self.config.get(essid_key, 'use_settings_globally'):
1204
elif self.config.has_section(bssid_key):
1207
return "500: Profile Not Found"
1209
for x in self.config.options(section):
1210
if not cur_network.has_key(x) or x.endswith("script"):
1211
cur_network[x] = misc.Noneify(self.config.get(section, x))
1212
for option in ['use_static_dns', 'use_global_dns', 'encryption',
1213
'use_settings_globally']:
1214
cur_network[option] = bool(cur_network.get(option))
1215
# Read the essid because we need to name those hidden
1216
# wireless networks now - but only read it if it is hidden.
1217
if cur_network["hidden"]:
1218
# check if there is an essid in the config file
1219
# if there isn't, .get( will return None
1220
stored_essid = self.config.get(section, 'essid')
1222
# set the current network's ESSID to the stored one
1223
cur_network['essid'] = stored_essid
1225
@dbus.service.method('org.wicd.daemon.wireless')
1226
def SaveWirelessNetworkProfile(self, id):
1227
""" Writes a wireless profile to disk. """
1228
def write_script_ent(prof, script):
1229
if not self.config.has_option(prof, script):
1230
self.config.set(prof, script, None)
1232
cur_network = self.LastScan[id]
1233
bssid_key = cur_network["bssid"]
1234
essid_key = "essid:%s" % cur_network["essid"]
1236
self.config.remove_section(bssid_key)
1237
self.config.add_section(bssid_key)
1239
# We want to write the essid in addition to bssid
1240
# sections if global settings are enabled.
1241
self.config.remove_section(essid_key)
1242
if cur_network.get("use_settings_globally", False):
1243
self.config.add_section(essid_key)
1245
for x in cur_network:
1246
# There's no reason to save these to a configfile...
1247
if x not in ['quality', 'strength', 'bitrates', 'has_profile']:
1248
self.config.set(bssid_key, x, cur_network[x])
1249
if cur_network.get("use_settings_globally", False):
1250
self.config.set(essid_key, x, cur_network[x])
1252
write_script_ent(bssid_key, "beforescript")
1253
write_script_ent(bssid_key, "afterscript")
1254
write_script_ent(bssid_key, "predisconnectscript")
1255
write_script_ent(bssid_key, "postdisconnectscript")
1257
if cur_network.get("use_settings_globally", False):
1258
write_script_ent(essid_key, "beforescript")
1259
write_script_ent(essid_key, "afterscript")
1260
write_script_ent(essid_key, "predisconnectscript")
1261
write_script_ent(essid_key, "postdisconnectscript")
1265
@dbus.service.method('org.wicd.daemon.wireless')
1266
def SaveWirelessNetworkProperty(self, id, option):
1267
""" Writes a particular wireless property to disk. """
1268
option = misc.sanitize_config(option)
1269
if option.endswith("script"):
1270
print 'You cannot save script information to disk through ' + \
1273
config = self.config
1274
cur_network = self.LastScan[id]
1275
essid_key = "essid:" + cur_network["essid"]
1277
config.set(cur_network["bssid"], option, str(cur_network[option]))
1279
# Write the global section as well, if required.
1280
if config.get(essid_key, 'use_settings_globally'):
1281
config.set(essid_key, option, str(cur_network[option]))
1284
@dbus.service.method('org.wicd.daemon.wireless')
1285
def RemoveGlobalEssidEntry(self, networkid):
1286
""" Removes the global entry for the networkid provided. """
1287
essid_key = "essid:" + str(self.LastScan[networkid])
1288
self.config.remove_section(essid_key)
1290
@dbus.service.method('org.wicd.daemon.wireless')
1291
def GetWpaSupplicantDrivers(self):
1292
""" Returns all valid wpa_supplicant drivers. """
1293
return self.wifi.GetWpaSupplicantDrivers()
1295
@dbus.service.method('org.wicd.daemon.wireless')
1296
def ReloadConfig(self):
1297
""" Reloads the active config file. """
1298
self.config.reload()
1300
@dbus.service.method('org.wicd.daemon.wireless')
1301
def GetWirelessInterfaces(self):
1302
''' Returns a list of wireless interfaces on the system. '''
1303
return wnettools.GetWirelessInterfaces()
1305
@dbus.service.signal(dbus_interface='org.wicd.daemon.wireless', signature='')
1306
def SendStartScanSignal(self):
1307
""" Emits a signal announcing a scan has started. """
1308
self._scanning = True
1310
@dbus.service.signal(dbus_interface='org.wicd.daemon.wireless', signature='')
1311
def SendEndScanSignal(self):
1312
""" Emits a signal announcing a scan has finished. """
1313
self._scanning = False
1315
def _wireless_autoconnect(self, fresh=True):
1316
""" Attempts to autoconnect to a wireless network. """
1317
print "No wired connection present, attempting to autoconnect " + \
1318
"to wireless network"
1319
if self.wifi.wireless_interface is None:
1320
print 'Autoconnect failed because wireless interface returned None'
1323
self.Scan(sync=True)
1325
for x, network in enumerate(self.LastScan):
1326
if self.config.has_section(network['bssid']):
1328
print network["essid"] + ' has profile'
1329
if bool(network.get('automatic')):
1331
if network.get('never'):
1332
print network["essid"],'marked never connect'
1335
print network["essid"],'has no never connect value'
1336
print 'trying to automatically connect to...' + \
1338
self.ConnectWireless(x)
1341
print "Unable to autoconnect, you'll have to manually connect"
1343
###########################
1344
###### Wired Daemon #######
1345
###########################
1347
class WiredDaemon(dbus.service.Object):
1348
""" DBus interface for wired connection operations. """
1349
def __init__(self, bus_name, daemon, wired=None, debug=False):
1350
""" Intitialize the wireless DBus interface. """
1351
dbus.service.Object.__init__(self, bus_name=bus_name,
1352
object_path="/org/wicd/daemon/wired")
1353
self.daemon = daemon
1355
self._debug_mode = debug
1356
self._cur_wired_prof_name = ""
1357
self.WiredNetwork = {}
1358
self.config = ConfigManager(wired_conf, debug=debug)
1360
def get_debug_mode(self):
1361
return self._debug_mode
1362
def set_debug_mode(self, mode):
1363
self._debug_mode = mode
1364
self.config.debug = mode
1365
debug_mode = property(get_debug_mode, set_debug_mode)
1367
@dbus.service.method('org.wicd.daemon.wired')
1368
def GetWiredIP(self, ifconfig=""):
1369
""" Returns the wired interface's ip address. """
1370
ip = self.wired.GetIP(ifconfig)
1373
@dbus.service.method('org.wicd.daemon.wired')
1374
def CheckIfWiredConnecting(self):
1375
""" Returns True if wired interface is connecting, otherwise False. """
1376
if self.wired.connecting_thread:
1377
return self.wired.connecting_thread.is_connecting
1381
@dbus.service.method('org.wicd.daemon.wired')
1382
def CheckWiredConnectingStatus(self):
1383
"""Returns the wired interface's status code. '"""
1384
if self.wired.connecting_thread:
1385
return self.wired.connecting_thread.GetStatus()
1389
@dbus.service.method('org.wicd.daemon.wired')
1390
def CheckWiredConnectingMessage(self):
1391
""" Returns the wired interface's status message. """
1392
if self.wired.connecting_thread:
1393
return _status_dict[self.CheckWiredConnectingStatus()]
1397
@dbus.service.method('org.wicd.daemon.wired')
1398
def DetectWiredInterface(self):
1399
""" Returns an automatically detected wireless interface. """
1400
iface = self.wired.DetectWiredInterface()
1402
print 'automatically detected wired interface ' + str(iface)
1404
print "Couldn't detect a wired interface."
1407
@dbus.service.method('org.wicd.daemon.wired')
1408
def SetWiredProperty(self, prop, value):
1409
""" Sets the given property to the given value. """
1410
if self.WiredNetwork:
1411
prop = misc.sanitize_config(prop)
1412
if prop.endswith('script'):
1413
print 'Setting script properties through the daemon' \
1414
+ ' is not permitted.'
1416
self.WiredNetwork[prop] = misc.to_unicode(misc.Noneify(value))
1419
print 'SetWiredProperty: WiredNetwork does not exist'
1422
@dbus.service.method('org.wicd.daemon.wired')
1423
def GetWiredProperty(self, property):
1424
""" Returns the requested wired property. """
1425
if self.WiredNetwork:
1426
value = self.WiredNetwork.get(property)
1429
print 'GetWiredProperty: WiredNetwork does not exist'
1432
@dbus.service.method('org.wicd.daemon.wired')
1433
def HasWiredDriver(self):
1434
""" Returns True if a driver is associated with this interface. """
1435
if self.wired.driver:
1440
@dbus.service.method('org.wicd.daemon.wired')
1441
def DisconnectWired(self):
1442
""" Disconnects the wired network. """
1443
self.wired.Disconnect()
1444
self.daemon.UpdateState()
1446
@dbus.service.method('org.wicd.daemon.wired')
1447
def CheckPluggedIn(self):
1448
""" Returns True if a ethernet cable is present, False otherwise. """
1449
if self.wired.wired_interface and self.wired.wired_interface != "None":
1450
return self.wired.CheckPluggedIn()
1454
@dbus.service.method('org.wicd.daemon.wired')
1455
def IsWiredUp(self):
1456
""" Returns a boolean specifying if wired iface is up or down. """
1457
return self.wired.IsUp()
1459
@dbus.service.method('org.wicd.daemon.wired')
1460
def EnableWiredInterface(self):
1461
""" Calls a method to enable the wired interface. """
1462
return self.wired.EnableInterface()
1464
@dbus.service.method('org.wicd.daemon.wired')
1465
def DisableWiredInterface(self):
1466
""" Calls a method to disable the wired interface. """
1467
return self.wired.DisableInterface()
1469
@dbus.service.method('org.wicd.daemon.wired')
1470
def ConnectWired(self):
1471
""" Connects to a wired network. """
1472
self.wired.before_script = self.GetWiredProperty("beforescript")
1473
self.wired.after_script = self.GetWiredProperty("afterscript")
1474
self.wired.pre_disconnect_script = self.GetWiredProperty("predisconnectscript")
1475
self.wired.post_disconnect_script = self.GetWiredProperty("postdisconnectscript")
1476
self.daemon.wireless_bus.wifi.Disconnect()
1477
# make sure disconnect scripts are run
1478
self.wired.Disconnect()
1479
self.daemon.SetForcedDisconnect(False)
1480
self.UnsetWiredLastUsed()
1481
self.config.set(self._cur_wired_prof_name, "lastused", True, write=True)
1482
self.wired.Connect(self.WiredNetwork, debug=self.debug_mode)
1483
self.daemon.UpdateState()
1485
@dbus.service.method('org.wicd.daemon.wired')
1486
def CreateWiredNetworkProfile(self, profilename, default=False):
1487
""" Creates a wired network profile. """
1490
profilename = misc.to_unicode(profilename)
1491
print "Creating wired profile for " + profilename
1492
if self.config.has_section(profilename):
1495
for option in ["ip", "broadcast", "netmask", "gateway", "search_domain",
1496
"dns_domain", "dns1", "dns2", "dns3", "beforescript",
1497
"afterscript", "predisconnectscript",
1498
"postdisconnectscript", "encryption_enabled"]:
1499
self.config.set(profilename, option, None)
1500
self.config.set(profilename, "default", default)
1501
self.config.set(profilename,"dhcphostname",os.uname()[1])
1505
@dbus.service.method('org.wicd.daemon.wired')
1506
def UnsetWiredLastUsed(self):
1507
""" Finds the previous lastused network, and sets lastused to False. """
1508
profileList = self.config.sections()
1509
for profile in profileList:
1510
if misc.to_bool(self.config.get(profile, "lastused")):
1511
self.config.set(profile, "lastused", False, write=True)
1513
@dbus.service.method('org.wicd.daemon.wired')
1514
def UnsetWiredDefault(self):
1515
""" Unsets the default option in the current default wired profile. """
1516
profileList = self.config.sections()
1517
for profile in profileList:
1518
if misc.to_bool(self.config.get(profile, "default")):
1519
self.config.set(profile, "default", False, write=True)
1521
@dbus.service.method('org.wicd.daemon.wired')
1522
def GetDefaultWiredNetwork(self):
1523
""" Returns the current default wired network. """
1524
profileList = self.config.sections()
1525
for profile in profileList:
1526
if misc.to_bool(self.config.get(profile, "default")):
1530
@dbus.service.method('org.wicd.daemon.wired')
1531
def GetLastUsedWiredNetwork(self):
1532
""" Returns the profile of the last used wired network. """
1533
profileList = self.config.sections()
1534
for profile in profileList:
1535
if misc.to_bool(self.config.get(profile, "lastused")):
1539
@dbus.service.method('org.wicd.daemon.wired')
1540
def DeleteWiredNetworkProfile(self, profilename):
1541
""" Deletes a wired network profile. """
1542
profilename = misc.to_unicode(profilename)
1543
print "Deleting wired profile for " + str(profilename)
1544
self.config.remove_section(profilename)
1547
@dbus.service.method('org.wicd.daemon.wired')
1548
def SaveWiredNetworkProfile(self, profilename):
1549
""" Writes a wired network profile to disk. """
1550
def write_script_ent(prof, script):
1551
if not self.config.has_option(prof, script):
1552
self.config.set(prof, script, None)
1554
profilename = profilename.strip()
1557
print "Warning: Bad wired profile name given, ignoring."
1558
return "500: Bad Profile name"
1560
print "saving wired profile %s" % profilename
1561
profilename = misc.to_unicode(profilename)
1562
self.config.remove_section(profilename)
1563
self.config.add_section(profilename)
1564
for x in self.WiredNetwork:
1565
self.config.set(profilename, x, self.WiredNetwork[x])
1567
write_script_ent(profilename, "beforescript")
1568
write_script_ent(profilename, "afterscript")
1569
write_script_ent(profilename, "predisconnectscript")
1570
write_script_ent(profilename, "postdisconnectscript")
1572
return "100: Profile Written"
1574
@dbus.service.method('org.wicd.daemon.wired')
1575
def ReadWiredNetworkProfile(self, profilename):
1576
""" Reads a wired network profile in as the currently active profile """
1578
profilename = misc.to_unicode(profilename)
1579
if self.config.has_section(profilename):
1581
print "Reading wired profile %s" % profilename
1582
for x in self.config.options(profilename):
1583
profile[x] = misc.Noneify(self.config.get(profilename, x))
1584
profile['use_global_dns'] = bool(profile.get('use_global_dns'))
1585
profile['use_static_dns'] = bool(profile.get('use_static_dns'))
1586
profile['encryption_enabled'] = bool(profile.get('encryption_enabled'))
1587
profile['profilename'] = profilename
1588
self.WiredNetwork = profile
1589
self._cur_wired_prof_name = profilename
1590
return "100: Loaded Profile"
1592
self._cur_wired_prof_name = ""
1593
self.WiredNetwork = {}
1594
return "500: Profile Not Found"
1596
@dbus.service.method('org.wicd.daemon.wired')
1597
def GetWiredProfileList(self):
1598
""" Returns a list of all wired profiles in wired-settings.conf. """
1599
sections = self.config.sections()
1604
@dbus.service.method('org.wicd.daemon.wired')
1605
def ReloadConfig(self):
1606
""" Reloads the active config file. """
1607
self.config.reload()
1609
@dbus.service.method('org.wicd.daemon.wired')
1610
def GetWiredInterfaces(self):
1611
''' Returns a list of wireless interfaces on the system. '''
1612
return wnettools.GetWiredInterfaces()
1617
wireless (and wired) connection daemon.
1620
\t-a\t--no-autoconnect\tDon't auto-scan/auto-connect.
1621
\t-f\t--no-daemon\tDon't daemonize (run in foreground).
1622
\t-e\t--no-stderr\tDon't redirect stderr.
1623
\t-n\t--no-poll\tDon't monitor network status.
1624
\t-o\t--no-stdout\tDon't redirect stdout.
1625
\t-h\t--help\t\tPrint this help.
1626
""" % (wpath.version + ' (bzr-r%s)' % wpath.revision)
1629
""" Disconnect from the controlling terminal.
1631
Fork twice, once to disconnect ourselves from the parent terminal and a
1632
second time to prevent any files we open from becoming our controlling
1636
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
1639
# Fork the first time to disconnect from the parent terminal and
1640
# exit the parent process.
1646
print >> sys.stderr, "Fork #1 failed: %d (%s)" % (e.errno, e.strerror)
1649
# Decouple from parent environment to stop us from being a zombie.
1652
# Fork the second time to prevent us from opening a file that will
1653
# become our controlling terminal.
1657
dirname = os.path.dirname(wpath.pidfile)
1658
if not os.path.exists(dirname):
1659
os.makedirs(dirname)
1660
pidfile = open(wpath.pidfile, 'w')
1661
pidfile.write(str(pid) + '\n')
1668
print >> sys.stderr, "Fork #2 failed: %d (%s)" % (e.errno, e.strerror)
1676
maxfd = os.sysconf("SC_OPEN_MAX")
1677
except (AttributeError, ValueError):
1680
for fd in range(0, maxfd):
1686
os.open(os.devnull, os.O_RDWR)
1688
# Duplicate standard input to standard output and standard error.
1694
""" The main daemon program.
1697
argv -- The arguments passed to the script.
1700
# back up resolv.conf before we do anything else
1702
backup_location = wpath.varlib + 'resolv.conf.orig'
1703
# don't back up if .orig exists, probably there cause
1705
if not os.path.exists(backup_location):
1706
shutil.copy2('/etc/resolv.conf', backup_location)
1707
os.chmod(backup_location, 0644)
1709
print 'error backing up resolv.conf'
1712
redirect_stderr = True
1713
redirect_stdout = True
1718
opts, args = getopt.getopt(sys.argv[1:], 'fenoahk',
1719
['help', 'no-daemon', 'no-poll', 'no-stderr', 'no-stdout',
1720
'no-autoconnect', 'kill'])
1721
except getopt.GetoptError:
1722
# Print help information and exit
1728
if o in ('-h', '--help'):
1731
if o in ('-e', '--no-stderr'):
1732
redirect_stderr = False
1733
if o in ('-o', '--no-stdout'):
1734
redirect_stdout = False
1735
if o in ('-f', '--no-daemon'):
1736
do_daemonize = False
1737
if o in ('-a', '--no-autoconnect'):
1738
auto_connect = False
1739
if o in ('-n', '--no-poll'):
1741
if o in ('-k', '--kill'):
1746
f = open(wpath.pidfile)
1748
#print >> sys.stderr, "No wicd instance active, aborting."
1751
# restore resolv.conf on quit
1753
shutil.move(wpath.varlib + 'resolv.conf.orig', '/etc/resolv.conf')
1754
os.chmod('/etc/resolv.conf', 0644)
1756
print 'error restoring resolv.conf'
1758
# connect to dbus, trigger a disconnect, then knock out the daemon
1759
from wicd import dbusmanager
1760
bus = dbusmanager.connect_to_dbus()
1761
dbus_ifaces = dbusmanager.get_dbus_ifaces()
1762
dbus_ifaces['daemon'].Disconnect()
1763
pid = int(f.readline())
1765
os.kill(pid,signal.SIGTERM)
1767
# quit, this should be the only option specified
1770
if os.path.exists(wpath.pidfile):
1771
print 'It seems like the daemon is already running.'
1772
print 'If it is not, please remove %s and try again.' % wpath.pidfile
1775
if not os.path.exists(wpath.networks):
1776
os.makedirs(wpath.networks)
1778
if do_daemonize: daemonize()
1780
if redirect_stderr or redirect_stdout:
1781
logpath = os.path.join(wpath.log, 'wicd.log')
1782
if not os.path.exists(wpath.log):
1783
os.makedirs(wpath.log)
1784
os.chmod(wpath.log, 0755)
1785
output = ManagedStdio(logpath)
1786
if os.path.exists(logpath):
1788
os.chmod(logpath, int(wpath.log_perms,8))
1790
print 'unable to chmod log file to %s' % wpath.log_perms
1795
group = grp.getgrnam(wpath.log_group)
1796
os.chown(logpath, 0, group[2])
1798
print 'unable to chown log file to %s' % group[2]
1800
if redirect_stdout: sys.stdout = output
1801
if redirect_stderr: sys.stderr = output
1803
print '---------------------------'
1804
print 'wicd initializing...'
1805
print '---------------------------'
1807
print 'wicd is version', wpath.version, wpath.revision
1809
# Open the DBUS session
1810
bus = dbus.SystemBus()
1811
wicd_bus = dbus.service.BusName('org.wicd.daemon', bus=bus)
1812
daemon = WicdDaemon(wicd_bus, auto_connect=auto_connect)
1815
child_pid = Popen([wpath.python, "-O",
1816
os.path.join(wpath.daemon, "monitor.py")],
1817
shell=False, close_fds=True).pid
1818
atexit.register(on_exit, child_pid)
1820
# Enter the main loop
1821
mainloop = gobject.MainLoop()
1824
except KeyboardInterrupt:
1826
daemon.DaemonClosing()
1828
def on_exit(child_pid):
1829
""" Called when a SIGTERM is caught, kills monitor.py before exiting. """
1831
print 'Daemon going down, killing wicd-monitor...'
1833
os.kill(child_pid, signal.SIGTERM)
1836
print 'Removing PID file...'
1837
if os.path.exists(wpath.pidfile):
1838
os.remove(wpath.pidfile)
1839
print 'Shutting down...'
1843
if __name__ == '__main__':
1844
if os.getuid() != 0:
1845
print ("Root privileges are required for the daemon to run properly." +
1848
gobject.threads_init()