~ubuntu-branches/ubuntu/lucid/wicd/lucid-updates

« back to all changes in this revision

Viewing changes to .pc/23-fix_local_privilege_escalation.patch/wicd/wicd-daemon.py

  • Committer: Package Import Robot
  • Author(s): Julian Taylor
  • Date: 2012-04-30 22:15:04 UTC
  • Revision ID: package-import@ubuntu.com-20120430221504-czr9b7d1s161lg1a
Tags: 1.7.0+ds1-2ubuntu0.1
* SECURITY UPDATE: local privilege escalation (LP: #979221)
  - debian/patches/23-fix_local_privilege_escalation.patch: sanitize
    config properties. Thanks to David Paleino <dapal@debian.org>
  - CVE-2012-2095
* SECURITY UPDATE: information leak in log files (LP: #992177)
  - debian/patches/24-mask-sensitive-info-from-log.patch: mask sensitive
    information in logs. Thanks to David Paleino <dapal@debian.org>
  - CVE-2012-0813

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
""" wicd - wireless connection daemon implementation.
 
5
 
 
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.
 
10
 
 
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.
 
14
 
 
15
"""
 
16
 
 
17
#
 
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
 
22
#
 
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.
 
26
#
 
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.
 
31
#
 
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/>.
 
34
#
 
35
 
 
36
import os
 
37
import shutil
 
38
import sys
 
39
import time
 
40
import getopt
 
41
import signal
 
42
import atexit
 
43
from subprocess import Popen
 
44
 
 
45
# DBUS
 
46
import gobject
 
47
import dbus
 
48
import dbus.service
 
49
if getattr(dbus, 'version', (0, 0, 0)) < (0, 80, 0):
 
50
    import dbus.glib
 
51
else:
 
52
    from dbus.mainloop.glib import DBusGMainLoop
 
53
    DBusGMainLoop(set_as_default=True)
 
54
 
 
55
# wicd specific libraries
 
56
from wicd import wpath
 
57
from wicd import networking
 
58
from wicd import misc
 
59
from wicd import wnettools
 
60
from wicd.misc import noneToBlankString
 
61
from wicd.logfile import ManagedStdio
 
62
from wicd.configmanager import ConfigManager
 
63
 
 
64
if __name__ == '__main__':
 
65
    wpath.chdir(__file__)
 
66
 
 
67
misc.RenameProcess("wicd")
 
68
 
 
69
wireless_conf = wpath.etc + "wireless-settings.conf"
 
70
wired_conf = wpath.etc + "wired-settings.conf"
 
71
dhclient_conf = wpath.etc + "dhclient.conf.template"
 
72
 
 
73
class WicdDaemon(dbus.service.Object):
 
74
    """ The main wicd daemon class.
 
75
 
 
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.
 
79
 
 
80
    """
 
81
    def __init__(self, bus_name, object_path="/org/wicd/daemon",
 
82
                 auto_connect=True):
 
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
 
97
        self.gui_open = False
 
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.dhcp_client = 0
 
105
        self.link_detect_tool = 0
 
106
        self.flush_tool = 0
 
107
        self.sudo_app = 0
 
108
 
 
109
        # This will speed up the scanning process - if a client doesn't 
 
110
        # need a fresh scan, just feed them the old one.  A fresh scan
 
111
        # can be done by calling Scan(fresh=True).
 
112
        self.LastScan = []
 
113
 
 
114
        # Load the config file
 
115
        self.ReadConfig()
 
116
 
 
117
        signal.signal(signal.SIGTERM, self.DaemonClosing)
 
118
        self.DaemonStarting()
 
119
 
 
120
        # Scan since we just got started
 
121
        if not auto_connect:
 
122
            print "--no-autoconnect detected, not autoconnecting..."
 
123
            self.SetForcedDisconnect(True)
 
124
        self.wireless_bus.Scan()
 
125
 
 
126
    def get_debug_mode(self):
 
127
        return self._debug_mode
 
128
    def set_debug_mode(self, mode):
 
129
        self._debug_mode = mode
 
130
        self.config.debug = mode
 
131
    debug_mode = property(get_debug_mode, set_debug_mode)
 
132
 
 
133
    @dbus.service.method('org.wicd.daemon')
 
134
    def Hello(self):
 
135
        """ Returns the version number. 
 
136
 
 
137
        This number is major-minor-micro. Major is only incremented if minor
 
138
        reaches > 9. Minor is incremented if changes that break core stucture
 
139
        are implemented. Micro is for everything else, and micro may be
 
140
        anything >= 0. This number is effective starting wicd v1.2.0.
 
141
 
 
142
        """
 
143
        return wpath.version
 
144
 
 
145
    @dbus.service.method('org.wicd.daemon')
 
146
    def SetWiredInterface(self, interface):
 
147
        """ Sets the wired interface for the daemon to use. """
 
148
        print "setting wired interface %s" % (str(interface))
 
149
        self.wired.wired_interface = noneToBlankString(interface)
 
150
        self.config.set("Settings", "wired_interface", interface, write=True)
 
151
 
 
152
    @dbus.service.method('org.wicd.daemon')
 
153
    def SetWirelessInterface(self, interface):
 
154
        """ Sets the wireless interface the daemon will use. """
 
155
        print "setting wireless interface %s" % (str(interface))
 
156
        self.wifi.wireless_interface = noneToBlankString(interface)
 
157
        self.config.set("Settings", "wireless_interface", interface, write=True)
 
158
 
 
159
    @dbus.service.method('org.wicd.daemon')
 
160
    def SetWPADriver(self, driver):
 
161
        """ Sets the wpa driver the wpa_supplicant will use. """
 
162
        print "setting wpa driver", str(driver)
 
163
        self.wifi.wpa_driver = driver
 
164
        self.config.set("Settings", "wpa_driver", driver, write=True)
 
165
 
 
166
    @dbus.service.method('org.wicd.daemon')
 
167
    def SetUseGlobalDNS(self, use):
 
168
        """ Sets a boolean which determines if global DNS is enabled. """
 
169
        print 'setting use global dns to', use
 
170
        use = misc.to_bool(use)
 
171
        self.config.set("Settings", "use_global_dns", use, write=True)
 
172
        self.use_global_dns = use
 
173
        self.wifi.use_global_dns = use
 
174
        self.wired.use_global_dns = use
 
175
 
 
176
    @dbus.service.method('org.wicd.daemon')
 
177
    def SetGlobalDNS(self, dns1=None, dns2=None, dns3=None,
 
178
                     dns_dom =None, search_dom=None):
 
179
        """ Sets the global dns addresses. """
 
180
        print "setting global dns"
 
181
        self.config.set("Settings", "global_dns_1", misc.noneToString(dns1))
 
182
        self.dns1 = dns1
 
183
        self.wifi.global_dns_1 = dns1
 
184
        self.wired.global_dns_1 = dns1
 
185
        self.config.set("Settings", "global_dns_2", misc.noneToString(dns2))
 
186
        self.dns2 = dns2
 
187
        self.wifi.global_dns_2 = dns2
 
188
        self.wired.global_dns_2 = dns2
 
189
        self.config.set("Settings", "global_dns_3", misc.noneToString(dns3))
 
190
        self.dns3 = dns3
 
191
        self.wifi.global_dns_3 = dns3
 
192
        self.wired.global_dns_3 = dns3
 
193
        self.config.set("Settings", "global_dns_dom", misc.noneToString(dns_dom))
 
194
        self.dns_dom = dns_dom
 
195
        self.wifi.dns_dom = dns_dom
 
196
        self.wired.dns_dom = dns_dom
 
197
        self.config.set("Settings", "global_search_dom", misc.noneToString(search_dom))
 
198
        self.search_dom = search_dom
 
199
        self.wifi.global_search_dom = search_dom
 
200
        self.wired.global_search_dom = search_dom
 
201
        print 'global dns servers are', dns1, dns2, dns3
 
202
        print 'domain is %s' % dns_dom
 
203
        print 'search domain is %s' % search_dom
 
204
        self.config.write()
 
205
 
 
206
    @dbus.service.method('org.wicd.daemon')
 
207
    def SetBackend(self, backend):
 
208
        """ Sets a new backend. """
 
209
        print "setting backend to %s" % backend
 
210
        backends = networking.BACKEND_MGR.get_available_backends()
 
211
        if backend not in backends:
 
212
            print "backend %s not available, trying to fallback to another" % backend
 
213
            try:
 
214
                backend = backends[0]
 
215
            except IndexError:
 
216
                print "ERROR: no backends available!"
 
217
                return
 
218
            else:
 
219
                print "Fell back to backend %s" % backend
 
220
        self.config.set("Settings", "backend", backend, write=True)
 
221
        if backend != self.GetCurrentBackend():
 
222
            self.suspended = True
 
223
            self.wifi.LoadBackend(backend)
 
224
            self.wired.LoadBackend(backend)
 
225
            self.SignalBackendChanged(self.GetBackendUpdateInterval())
 
226
            self.SetSuspend(False)
 
227
 
 
228
    @dbus.service.method('org.wicd.daemon')
 
229
    def GetCurrentBackend(self):
 
230
        """ Returns the currently loaded backend. """
 
231
        return networking.get_current_backend()
 
232
 
 
233
    @dbus.service.method('org.wicd.daemon')
 
234
    def GetBackendUpdateInterval(self):
 
235
        """ Returns status update interval for the loaded backend. """
 
236
        return networking.get_backend_update_interval()
 
237
 
 
238
    @dbus.service.method('org.wicd.daemon')
 
239
    def GetBackendDescription(self, backend_name):
 
240
        """ Returns the description of the given backend. """
 
241
        return networking.get_backend_description(backend_name)
 
242
 
 
243
    @dbus.service.method('org.wicd.daemon')
 
244
    def GetBackendDescriptionDict(self):
 
245
        """ Returns a dict of all backend names mapped to their description. """
 
246
        return networking.get_backend_description_dict()
 
247
 
 
248
    @dbus.service.method('org.wicd.daemon')
 
249
    def GetSavedBackend(self):
 
250
        """ Returns the backend saved to disk. """
 
251
        return self.config.get("Settings", "backend")
 
252
 
 
253
    @dbus.service.method('org.wicd.daemon')
 
254
    def GetBackendList(self):
 
255
        """ Returns a list of all backends available. """
 
256
        return networking.get_backend_list()
 
257
 
 
258
    @dbus.service.method('org.wicd.daemon')
 
259
    def GetUseGlobalDNS(self):
 
260
        """ Returns a boolean that determines if global dns is enabled. """
 
261
        return bool(self.use_global_dns)
 
262
 
 
263
    @dbus.service.method('org.wicd.daemon')
 
264
    def GetWPADriver(self):
 
265
        """ Returns the wpa driver the daemon is using. """
 
266
        return str(self.wifi.wpa_driver)
 
267
 
 
268
    @dbus.service.method('org.wicd.daemon')
 
269
    def GetWiredInterface(self):
 
270
        """ Returns the wired interface. """
 
271
        return str(self.wired.wired_interface)
 
272
 
 
273
    @dbus.service.method('org.wicd.daemon')
 
274
    def GetWirelessInterface(self):
 
275
        """ Returns the wireless interface the daemon is using. """
 
276
        return str(self.wifi.wireless_interface)
 
277
 
 
278
    @dbus.service.method('org.wicd.daemon')
 
279
    def NeedsExternalCalls(self):
 
280
        """ Returns true if the loaded backend needs external calls. """
 
281
        if self.wifi:
 
282
            return self.wifi.NeedsExternalCalls()
 
283
        elif self.wired:
 
284
            return self.wired.NeedsExternalCalls()
 
285
        else:
 
286
            return True
 
287
 
 
288
    @dbus.service.method('org.wicd.daemon')
 
289
    def SetDebugMode(self, debug):
 
290
        """ Sets if debugging mode is on or off. """
 
291
        self.config.set("Settings", "debug_mode", debug, write=True)
 
292
        self.debug_mode = misc.to_bool(debug)
 
293
        self.wifi.debug = debug
 
294
        self.wired.debug = debug
 
295
        self.wireless_bus.debug_mode = debug
 
296
        self.wired_bus.debug_mode = debug
 
297
 
 
298
    @dbus.service.method('org.wicd.daemon')
 
299
    def GetDebugMode(self):
 
300
        """ Returns whether debugging is enabled. """
 
301
        return bool(self.debug_mode)
 
302
 
 
303
    @dbus.service.method('org.wicd.daemon')
 
304
    def Disconnect(self):
 
305
        """ Disconnects all networks. """
 
306
        self.SetForcedDisconnect(True)
 
307
        self.wifi.Disconnect()
 
308
        self.wired.Disconnect()
 
309
 
 
310
    @dbus.service.method('org.wicd.daemon')
 
311
    def FormatSignalForPrinting(self, signal):
 
312
        """ Returns the suffix to display after the signal strength number. """
 
313
        if self.GetSignalDisplayType() == 1:
 
314
            return (signal + " dBm")
 
315
        else:
 
316
            try:
 
317
                if int(signal) == 101:
 
318
                    return '??%'
 
319
                else:
 
320
                    return (signal + "%")
 
321
            except ValueError:
 
322
                return (signal + "%")
 
323
 
 
324
    @dbus.service.method('org.wicd.daemon')
 
325
    def SetSuspend(self, val):
 
326
        """ Toggles whether or not monitoring connection status is suspended """
 
327
        self.suspended = val
 
328
        if self.suspended:
 
329
            self.Disconnect()
 
330
        else:
 
331
            self.SetForcedDisconnect(False)
 
332
 
 
333
    @dbus.service.method('org.wicd.daemon')
 
334
    def GetSuspend(self):
 
335
        """ Returns True if the computer is in the suspend state. """
 
336
        return self.suspended
 
337
 
 
338
    @dbus.service.method('org.wicd.daemon')
 
339
    def AutoConnect(self, fresh):
 
340
        """ Attempts to autoconnect to a wired or wireless network.
 
341
 
 
342
        Autoconnect will first try to connect to a wired network, if that 
 
343
        fails it tries a wireless connection.
 
344
 
 
345
        """
 
346
        print "Autoconnecting..."
 
347
        if self.CheckIfConnecting():
 
348
            if self.debug_mode:
 
349
                print 'Already connecting, doing nothing.'
 
350
            return
 
351
        # We don't want to rescan/connect if the gui is open.
 
352
        if self.gui_open:
 
353
            if self.debug_mode:
 
354
                print "Skipping autoconnect because GUI is open."
 
355
            return
 
356
        if self.wired_bus.CheckPluggedIn():
 
357
            if self.debug_mode:
 
358
                print "Starting wired autoconnect..."
 
359
            self._wired_autoconnect(fresh)
 
360
        else:
 
361
            if self.debug_mode:
 
362
                print "Starting wireless autoconnect..."
 
363
            self.wireless_bus._wireless_autoconnect(fresh)
 
364
 
 
365
    @dbus.service.method('org.wicd.daemon')
 
366
    def GetAutoReconnect(self):
 
367
        """ Returns the value of self.auto_reconnect. See SetAutoReconnect. """
 
368
        return bool(self.auto_reconnect)
 
369
 
 
370
    @dbus.service.method('org.wicd.daemon')
 
371
    def SetAutoReconnect(self, value):
 
372
        """ Sets the value of self.auto_reconnect.
 
373
 
 
374
        If True, wicd will try to reconnect as soon as it detects that
 
375
        an internet connection is lost.  If False, it will do nothing,
 
376
        and wait for the user to initiate reconnection.
 
377
 
 
378
        """
 
379
        print 'setting automatically reconnect when connection drops %s' % value
 
380
        self.config.set("Settings", "auto_reconnect", misc.to_bool(value), 
 
381
                        write=True)
 
382
        self.auto_reconnect = misc.to_bool(value)
 
383
 
 
384
    @dbus.service.method('org.wicd.daemon')
 
385
    def GetGlobalDNSAddresses(self):
 
386
        """ Returns the global dns addresses. """
 
387
        return (misc.noneToString(self.dns1), misc.noneToString(self.dns2),
 
388
                misc.noneToString(self.dns3), misc.noneToString(self.dns_dom),
 
389
                misc.noneToString(self.search_dom))
 
390
 
 
391
    @dbus.service.method('org.wicd.daemon')
 
392
    def CheckIfConnecting(self):
 
393
        """ Returns if a network connection is being made. """
 
394
        if self.wired_bus.CheckIfWiredConnecting() or \
 
395
           self.wireless_bus.CheckIfWirelessConnecting():
 
396
            return True
 
397
        else:
 
398
            return False
 
399
 
 
400
    @dbus.service.method('org.wicd.daemon')
 
401
    def CancelConnect(self):
 
402
        """ Cancels the wireless connection attempt """
 
403
        print 'canceling connection attempt'
 
404
        if self.wifi.connecting_thread:
 
405
            self.wifi.connecting_thread.should_die = True
 
406
            self.wifi.ReleaseDHCP()
 
407
            # We have to actually kill dhcp if its still hanging
 
408
            # around.  It could still be trying to get a lease.
 
409
            self.wifi.KillDHCP()
 
410
            self.wifi.StopWPA()
 
411
            self.wifi.connecting_thread.connect_result = 'aborted'
 
412
        if self.wired.connecting_thread:
 
413
            self.wired.connecting_thread.should_die = True
 
414
            self.wired.ReleaseDHCP()
 
415
            self.wired.KillDHCP()
 
416
            self.wired.connecting_thread.connect_result = 'aborted'
 
417
 
 
418
    @dbus.service.method('org.wicd.daemon')
 
419
    def GetCurrentInterface(self):
 
420
        """ Returns the active interface """
 
421
        return self.current_interface
 
422
 
 
423
    @dbus.service.method('org.wicd.daemon')    
 
424
    def SetCurrentInterface(self, iface):
 
425
        """ Sets the current active interface """
 
426
        self.current_interface = str(iface)
 
427
 
 
428
    @dbus.service.method('org.wicd.daemon')
 
429
    def SetNeedWiredProfileChooser(self, val):
 
430
        """ Sets the need_wired_profile_chooser variable.
 
431
 
 
432
        If set to True, that alerts the wicd frontend to display the chooser,
 
433
        if False the frontend will do nothing.  This function is only needed
 
434
        when the frontend starts up, to determine if the chooser was requested
 
435
        before the frontend was launched.
 
436
 
 
437
        """
 
438
        self.need_profile_chooser = misc.to_bool(val)
 
439
 
 
440
    @dbus.service.method('org.wicd.daemon')
 
441
    def ShouldAutoReconnect(self):
 
442
        """ Returns True if it's the right time to try autoreconnecting. """
 
443
        if self.GetAutoReconnect() and not self.CheckIfConnecting() and \
 
444
           not self.GetForcedDisconnect() and not self.auto_connecting and \
 
445
           not self.gui_open:
 
446
            return True
 
447
        else:
 
448
            return False
 
449
 
 
450
    @dbus.service.method('org.wicd.daemon')
 
451
    def GetForcedDisconnect(self):
 
452
        """ Returns the forced_disconnect status.  See SetForcedDisconnect. """
 
453
        return bool(self.forced_disconnect)
 
454
 
 
455
    @dbus.service.method('org.wicd.daemon')
 
456
    def SetForcedDisconnect(self, value):
 
457
        """ Sets the forced_disconnect status.
 
458
 
 
459
        Set to True when a user manually disconnects or cancels a connection.
 
460
        It gets set to False as soon as the connection process is manually
 
461
        started.
 
462
 
 
463
        """
 
464
        if self.debug_mode and value: print "Forced disconnect on"
 
465
        self.forced_disconnect = bool(value)
 
466
 
 
467
    @dbus.service.method('org.wicd.daemon')
 
468
    def GetSignalDisplayType(self):
 
469
        """ Returns the signal display type.
 
470
 
 
471
        Returns either 0 or 1.
 
472
        0 for signal strength as a percentage
 
473
        1 for signal strength measured in dBm
 
474
 
 
475
        """
 
476
        return int(self.signal_display_type)
 
477
 
 
478
    @dbus.service.method('org.wicd.daemon')
 
479
    def SetSignalDisplayType(self, value):
 
480
        """ Sets the signal display type and writes it the wicd config file. """
 
481
        self.config.set("Settings", "signal_display_type", value, write=True)
 
482
        self.signal_display_type = int(value)
 
483
 
 
484
    @dbus.service.method('org.wicd.daemon')
 
485
    def GetGUIOpen(self):
 
486
        """ Returns the value of gui_open.
 
487
 
 
488
        Returns the vlaue of gui_open, which is a boolean that keeps track
 
489
        of the state of the wicd GUI.  If the GUI is open, wicd will not
 
490
        try to automatically reconnect to networks, as this behavior can
 
491
        be annoying for the user while trying to use the GUI.
 
492
 
 
493
        NOTE: It's possible for this to become out of sync, particularly if
 
494
        the wicd.py is not exited properly while the GUI is open.  We should
 
495
        probably implement some kind of pid system to do it properly.
 
496
 
 
497
        ANOTHER NOTE: This isn't used by anything yet!
 
498
 
 
499
        """
 
500
        return bool(self.gui_open)
 
501
 
 
502
    @dbus.service.method('org.wicd.daemon')
 
503
    def SetGUIOpen(self, val):
 
504
        """ Sets the value of gui_open. """
 
505
        self.gui_open = bool(val)
 
506
 
 
507
    @dbus.service.method('org.wicd.daemon')
 
508
    def SetAlwaysShowWiredInterface(self, value):
 
509
        """ Sets always_show_wired_interface to the given value. """
 
510
        self.config.set("Settings", "always_show_wired_interface", 
 
511
                        misc.to_bool(value), write=True)
 
512
        self.always_show_wired_interface = misc.to_bool(value)
 
513
 
 
514
    @dbus.service.method('org.wicd.daemon')
 
515
    def GetAlwaysShowWiredInterface(self):
 
516
        """ Returns always_show_wired_interface """
 
517
        return bool(self.always_show_wired_interface)
 
518
 
 
519
    @dbus.service.method('org.wicd.daemon')
 
520
    def SetWiredAutoConnectMethod(self, method):
 
521
        """ Sets which method to use to autoconnect to wired networks. """
 
522
        # 1 = default profile
 
523
        # 2 = show list
 
524
        # 3 = last used profile
 
525
        self.config.set("Settings", "wired_connect_mode", int(method),
 
526
                        write=True)
 
527
        self.wired_connect_mode = int(method)
 
528
        self.wired_bus.connect_mode = int(method)
 
529
        
 
530
    @dbus.service.method('org.wicd.daemon')
 
531
    def SetShouldVerifyAp(self, value):
 
532
        """ Enable/disable wireless AP verification.
 
533
        
 
534
        If this is True, wicd will try to verify that we are associated
 
535
        with the Wireless AP after a connection attempt appears to
 
536
        succeed.
 
537
        
 
538
        """
 
539
        self.config.set("Settings", "should_verify_ap", int(value), write=True)
 
540
        self.wifi.should_verify_ap = misc.to_bool(value)
 
541
        
 
542
    @dbus.service.method('org.wicd.daemon')
 
543
    def GetShouldVerifyAp(self):
 
544
        """ Returns current value for WAP connection verification. """
 
545
        return bool(self.wifi.should_verify_ap)
 
546
 
 
547
    @dbus.service.method('org.wicd.daemon')
 
548
    def GetWiredAutoConnectMethod(self):
 
549
        """ Returns the wired autoconnect method. """
 
550
        return int(self.wired_connect_mode)
 
551
 
 
552
    @dbus.service.method('org.wicd.daemon')
 
553
    def GetPreferWiredNetwork(self):
 
554
        """ Returns True if wired network preference is set. 
 
555
 
 
556
        If this is True, wicd will switch from a wireless connection
 
557
        to a wired one if an ethernet connection is available.
 
558
 
 
559
        """
 
560
        return self.prefer_wired
 
561
 
 
562
    @dbus.service.method('org.wicd.daemon')
 
563
    def SetPreferWiredNetwork(self, value):
 
564
        """ Sets the prefer_wired state. """
 
565
        self.config.set("Settings", "prefer_wired", bool(value), write=True)
 
566
        self.prefer_wired = bool(value)
 
567
 
 
568
    @dbus.service.method('org.wicd.daemon')
 
569
    def SetConnectionStatus(self, state, info):
 
570
        """ Sets the connection status.
 
571
 
 
572
        Keyword arguments:
 
573
        state - An int representing the state of the connection as defined
 
574
        in misc.py.
 
575
 
 
576
        info - a list of strings containing data about the connection state.  
 
577
        The contents of this list are dependent on the connection state.
 
578
 
 
579
        state - info contents:
 
580
        NOT_CONNECTED - info[0] = ""
 
581
        CONNECTING - info[0] = "wired" or "wireless"
 
582
                     info[1] = None if wired, an essid if wireless
 
583
        WIRED - info[0] = IP Adresss
 
584
        WIRELESS - info[0] = IP Address
 
585
                   info[1] = essid
 
586
                   info[2] = signal strength
 
587
                   info[3] = internal networkid
 
588
                   info[4] = bitrate
 
589
        SUSPENDED - info[0] = ""
 
590
 
 
591
 
 
592
        """
 
593
        self.connection_state = state
 
594
        self.connection_info = info
 
595
 
 
596
    @dbus.service.method('org.wicd.daemon', out_signature='(uas)')
 
597
    def GetConnectionStatus(self):
 
598
        """ Returns the current connection state in list form. 
 
599
 
 
600
        See SetConnectionStatus for more information about the
 
601
        data structure being returned.
 
602
 
 
603
        """
 
604
        return [self.connection_state, self.connection_info]
 
605
 
 
606
    @dbus.service.method('org.wicd.daemon')
 
607
    def GetNeedWiredProfileChooser(self):
 
608
        """ Returns need_profile_chooser.
 
609
 
 
610
        Returns a boolean specifying if the wired profile chooser needs to
 
611
        be launched.
 
612
 
 
613
        """
 
614
        return bool(self.need_profile_chooser)
 
615
 
 
616
    @dbus.service.method("org.wicd.daemon")
 
617
    def GetAppAvailable(self, app):
 
618
        """ Determine if a given  application is available."""
 
619
        return bool(self.wifi.AppAvailable(app) or self.wired.AppAvailable(app))
 
620
 
 
621
    @dbus.service.method('org.wicd.daemon')
 
622
    def GetDHCPClient(self):
 
623
        """ Returns the current DHCP client constant.
 
624
 
 
625
        See misc.py for a definition of the constants.
 
626
 
 
627
        """
 
628
        return self.dhcp_client
 
629
 
 
630
    @dbus.service.method('org.wicd.daemon')
 
631
    def SetDHCPClient(self, client):
 
632
        """ Sets the DHCP client constant.
 
633
 
 
634
        See misc.py for a definition of the constants.
 
635
 
 
636
        """
 
637
        print "Setting dhcp client to %i" % (int(client))
 
638
        self.dhcp_client = int(client)
 
639
        self.wifi.dhcp_client = int(client)
 
640
        self.wired.dhcp_client = int(client)
 
641
        self.config.set("Settings", "dhcp_client", client, write=True)
 
642
 
 
643
    @dbus.service.method('org.wicd.daemon')
 
644
    def GetLinkDetectionTool(self):
 
645
        """ Returns the current link detection tool constant. """
 
646
        return self.link_detect_tool
 
647
 
 
648
    @dbus.service.method('org.wicd.daemon')
 
649
    def SetLinkDetectionTool(self, link_tool):
 
650
        """ Sets the link detection tool. 
 
651
 
 
652
        Sets the value of the tool wicd should use to detect if a
 
653
        cable is plugged in.  If using a backend that doesn't use
 
654
        an external call to get this information (such as ioctl)
 
655
        it will instead use the ioctls provided by the specified
 
656
        tool to query for link status.
 
657
 
 
658
        """
 
659
        self.link_detect_tool = int(link_tool)
 
660
        self.wired.link_detect = int(link_tool)
 
661
        self.config.set("Settings", "link_detect_tool", link_tool, write=True)
 
662
 
 
663
    @dbus.service.method('org.wicd.daemon')
 
664
    def GetFlushTool(self):
 
665
        """ Returns the current flush tool constant. """
 
666
        return self.flush_tool
 
667
 
 
668
    @dbus.service.method('org.wicd.daemon')
 
669
    def SetFlushTool(self, flush_tool):
 
670
        """ Sets the flush tool.
 
671
 
 
672
        Sets the value of the tool wicd should use to flush routing tables.
 
673
        The value is associated with a particular tool, as specified in
 
674
        misc.py
 
675
 
 
676
        """
 
677
        self.flush_tool = int(flush_tool)
 
678
        self.wired.flush_tool = int(flush_tool)
 
679
        self.wifi.flush_tool = int(flush_tool)
 
680
        self.config.set("Settings", "flush_tool", flush_tool, write=True)
 
681
 
 
682
    @dbus.service.method('org.wicd.daemon')
 
683
    def GetSudoApp(self):
 
684
        """ Get the preferred sudo app. """
 
685
        return self.sudo_app
 
686
 
 
687
    @dbus.service.method('org.wicd.daemon')
 
688
    def SetSudoApp(self, sudo_app):
 
689
        """ Set the preferred sudo app. """
 
690
        self.sudo_app = sudo_app
 
691
        self.config.set("Settings", "sudo_app", sudo_app, write=True)
 
692
 
 
693
    @dbus.service.method('org.wicd.daemon')
 
694
    def WriteWindowSize(self, width, height, win_name):
 
695
        """ Write the desired default window size.
 
696
 
 
697
        win_name should be either 'main' or 'pref', and specifies
 
698
        whether the size being given applies to the main GUI window
 
699
        or the preferences dialog window.
 
700
 
 
701
        """
 
702
        if win_name:
 
703
            height_str = '%s_height' % win_name
 
704
            width_str = '%s_width' % win_name
 
705
        # probably don't need the else, but the previous code
 
706
        # had an else that caught everything
 
707
        else:
 
708
            height_str = "pref_height"
 
709
            width_str = "pref_width"
 
710
 
 
711
        self.config.set("Settings", width_str, width)
 
712
        self.config.set("Settings", height_str, height)
 
713
        self.config.write()
 
714
 
 
715
    @dbus.service.method('org.wicd.daemon')
 
716
    def ReadWindowSize(self, win_name):
 
717
        """Returns a list containing the desired default window size
 
718
 
 
719
        Attempts to read the default size from the config file,
 
720
        and if that fails, returns a default of 605 x 400.
 
721
 
 
722
        """
 
723
        default_width, default_height = (-1, -1)
 
724
        if win_name:
 
725
            height_str = '%s_height' % win_name
 
726
            width_str = '%s_width' % win_name
 
727
        # probably don't need the else, but the previous code
 
728
        # had an else that caught everything
 
729
        else:
 
730
            height_str = "pref_height"
 
731
            width_str = "pref_width"
 
732
 
 
733
        width = self.config.get("Settings", width_str, default=default_width)
 
734
        height = self.config.get("Settings", height_str, default=default_height)
 
735
        self.config.write()
 
736
 
 
737
        size = []
 
738
        size.append(int(width))
 
739
        size.append(int(height))
 
740
        return size
 
741
 
 
742
    def _wired_autoconnect(self, fresh=True):
 
743
        """ Attempts to autoconnect to a wired network. """
 
744
        wiredb = self.wired_bus
 
745
        if self.GetWiredAutoConnectMethod() == 3 and \
 
746
           not self.GetNeedWiredProfileChooser():
 
747
            # attempt to smartly connect to a wired network
 
748
            # by using various wireless networks detected
 
749
            # and by using plugged in USB devices
 
750
            print self.LastScan
 
751
        if self.GetWiredAutoConnectMethod() == 2 and \
 
752
           not self.GetNeedWiredProfileChooser():
 
753
            self.LaunchChooser()
 
754
            return True
 
755
 
 
756
        # Default Profile.
 
757
        elif self.GetWiredAutoConnectMethod() == 1:
 
758
            network = wiredb.GetDefaultWiredNetwork()
 
759
            if not network:
 
760
                print "Couldn't find a default wired connection," + \
 
761
                      " wired autoconnect failed."
 
762
                self.wireless_bus._wireless_autoconnect(fresh)
 
763
                return
 
764
 
 
765
        # Last-Used.
 
766
        else:
 
767
            network = wiredb.GetLastUsedWiredNetwork()
 
768
            if not network:
 
769
                print "no previous wired profile available, wired " + \
 
770
                      "autoconnect failed."
 
771
                self.wireless_bus._wireless_autoconnect(fresh)
 
772
                return
 
773
 
 
774
        wiredb.ReadWiredNetworkProfile(network)
 
775
        wiredb.ConnectWired()
 
776
        print "Attempting to autoconnect with wired interface..."
 
777
        self.auto_connecting = True
 
778
        time.sleep(1.5)
 
779
        try:
 
780
            gobject.timeout_add_seconds(3, self._monitor_wired_autoconnect, 
 
781
                                        fresh)
 
782
        except:
 
783
            gobject.timeout_add(3000, self._monitor_wired_autoconnect, fresh)
 
784
        return True
 
785
 
 
786
    def _monitor_wired_autoconnect(self, fresh):
 
787
        """ Monitor a wired auto-connection attempt.
 
788
 
 
789
        Helper method called on a timer that monitors a wired
 
790
        connection attempt and makes decisions about what to
 
791
        do next based on the result.
 
792
 
 
793
        """
 
794
        wiredb = self.wired_bus
 
795
        if wiredb.CheckIfWiredConnecting():
 
796
            return True
 
797
        elif wiredb.GetWiredIP():
 
798
            self.auto_connecting = False
 
799
            return False
 
800
        elif not self.wireless_bus.CheckIfWirelessConnecting():
 
801
            self.wireless_bus._wireless_autoconnect(fresh)
 
802
            return False
 
803
        self.auto_connecting = False
 
804
        return False
 
805
 
 
806
    @dbus.service.method("org.wicd.daemon")
 
807
    def ConnectResultsAvailable(self):
 
808
        if ((self.wired.connecting_thread and self.wired.connecting_thread.connect_result) or 
 
809
            (self.wifi.connecting_thread and self.wifi.connecting_thread.connect_result)):
 
810
            return True
 
811
        else:
 
812
            return False
 
813
 
 
814
    @dbus.service.method("org.wicd.daemon")
 
815
    def SendConnectResultsIfAvail(self):
 
816
        if self.ConnectResultsAvailable():
 
817
            self.SendConnectResult()
 
818
 
 
819
    @dbus.service.method("org.wicd.daemon")
 
820
    def SendConnectResult(self):
 
821
        if self.wired.connecting_thread and self.wired.connecting_thread.connect_result:
 
822
            self.ConnectResultsSent(self.wired.connecting_thread.connect_result)
 
823
            self.wired.connecting_thread.connect_result = ""
 
824
        elif self.wifi.connecting_thread and self.wifi.connecting_thread.connect_result:
 
825
            self.ConnectResultsSent(self.wifi.connecting_thread.connect_result)
 
826
            self.wifi.connecting_thread.connect_result = ""
 
827
 
 
828
    @dbus.service.signal(dbus_interface="org.wicd.daemon",signature='s')
 
829
    def ConnectResultsSent(self, result):
 
830
        print "Sending connection attempt result %s" % result
 
831
 
 
832
    @dbus.service.method("org.wicd.daemon")
 
833
    @dbus.service.signal(dbus_interface="org.wicd.daemon", signature='')
 
834
    def UpdateState(self):
 
835
        pass
 
836
 
 
837
    @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='')
 
838
    def LaunchChooser(self):
 
839
        """ Emits the wired profile chooser dbus signal. """
 
840
        print 'calling wired profile chooser'
 
841
        self.SetNeedWiredProfileChooser(True)
 
842
 
 
843
    @dbus.service.signal(dbus_interface="org.wicd.daemon", signature='')
 
844
    def DaemonStarting(self):
 
845
        """ Emits a signa indicating the daemon is starting. """
 
846
        pass
 
847
 
 
848
    @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='')
 
849
    def DaemonClosing(self):
 
850
        """ Emits a signal indicating the daemon will be closing. """
 
851
        pass
 
852
 
 
853
    @dbus.service.method('org.wicd.daemon', in_signature='uav')
 
854
    def EmitStatusChanged(self, state, info):
 
855
        """ Calls the StatusChanged signal method. """
 
856
        self.StatusChanged(state, info)
 
857
 
 
858
    @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='uav')
 
859
    def StatusChanged(self, state, info):
 
860
        """ Emits a "status changed" dbus signal.
 
861
 
 
862
        This D-Bus signal is emitted when the connection status changes.
 
863
        This signal can be hooked to monitor the network state.
 
864
 
 
865
        """
 
866
        pass
 
867
    
 
868
    @dbus.service.signal(dbus_interface='org.wicd.daemon', signature='i')
 
869
    def SignalBackendChanged(self, interval):
 
870
        """ Emits a signal when the current backend changes. """
 
871
        pass
 
872
 
 
873
    def ReadConfig(self):
 
874
        """ Reads the manager-settings.conf file.
 
875
 
 
876
        Reads the manager-settings.conf file and loads the stored
 
877
        values into memory.
 
878
 
 
879
        """
 
880
        b_wired = self.wired_bus
 
881
        b_wifi = self.wireless_bus
 
882
        app_conf = self.config
 
883
        # Load the backend.
 
884
        be_def = 'external'
 
885
        self.SetBackend(app_conf.get("Settings", "backend", default=be_def))
 
886
 
 
887
        # Load network interfaces.
 
888
        iface = self.wireless_bus.DetectWirelessInterface()
 
889
        if not iface: iface = 'wlan0'
 
890
        self.SetWirelessInterface(app_conf.get("Settings", "wireless_interface",
 
891
                                               default=iface))
 
892
        iface = self.wired_bus.DetectWiredInterface()
 
893
        if not iface: iface = 'eth0'
 
894
        self.SetWiredInterface(app_conf.get("Settings", "wired_interface",
 
895
                                            default=iface))
 
896
 
 
897
        self.SetWPADriver(app_conf.get("Settings", "wpa_driver", default="wext"))
 
898
        self.SetAlwaysShowWiredInterface(app_conf.get("Settings",
 
899
                                                      "always_show_wired_interface",
 
900
                                                      default=False))
 
901
        self.SetUseGlobalDNS(app_conf.get("Settings", "use_global_dns",
 
902
                                          default=False))
 
903
        dns1 = app_conf.get("Settings", "global_dns_1", default='None')
 
904
        dns2 = app_conf.get("Settings", "global_dns_2", default='None')
 
905
        dns3 = app_conf.get("Settings", "global_dns_3", default='None')
 
906
        dns_dom = app_conf.get("Settings", "global_dns_dom", default='None')
 
907
        search_dom = app_conf.get("Settings", "global_search_dom", default='None')
 
908
        self.SetGlobalDNS(dns1, dns2, dns3, dns_dom, search_dom)
 
909
        self.SetAutoReconnect(app_conf.get("Settings", "auto_reconnect",
 
910
                                           default=True))
 
911
        self.SetDebugMode(app_conf.get("Settings", "debug_mode", default=False))
 
912
        self.SetWiredAutoConnectMethod(app_conf.get("Settings",
 
913
                                                    "wired_connect_mode",
 
914
                                                    default=1))
 
915
        self.SetSignalDisplayType(app_conf.get("Settings", 
 
916
                                               "signal_display_type",
 
917
                                               default=0))
 
918
        self.SetShouldVerifyAp(app_conf.get("Settings", "should_verify_ap",
 
919
                                            default=1))
 
920
        self.SetDHCPClient(app_conf.get("Settings", "dhcp_client", default=0))
 
921
        self.SetLinkDetectionTool(app_conf.get("Settings", "link_detect_tool",
 
922
                                               default=0))
 
923
        self.SetFlushTool(app_conf.get("Settings", "flush_tool", default=0))
 
924
        self.SetSudoApp(app_conf.get("Settings", "sudo_app", default=0))
 
925
        self.SetPreferWiredNetwork(app_conf.get("Settings", "prefer_wired", 
 
926
                                                default=False))
 
927
        app_conf.write()
 
928
 
 
929
        if os.path.isfile(wireless_conf):
 
930
            print "Wireless configuration file found..."
 
931
        else:
 
932
            print "Wireless configuration file not found, creating..."
 
933
            open(wireless_conf, "w").close()
 
934
 
 
935
        if os.path.isfile(wired_conf):
 
936
            print "Wired configuration file found..."
 
937
        else:
 
938
            print "Wired configuration file not found, creating a default..."
 
939
            # Create the file and a default profile
 
940
            open(wired_conf, "w").close()
 
941
            b_wired.CreateWiredNetworkProfile("wired-default", default=True)
 
942
 
 
943
        if not os.path.isfile(dhclient_conf):
 
944
            print "dhclient.conf.template not found, copying..."
 
945
            shutil.copy(dhclient_conf + ".default", dhclient_conf)            
 
946
        # Hide the files, so the keys aren't exposed.
 
947
        print "chmoding configuration files 0600..."
 
948
        os.chmod(app_conf.get_config(), 0600)
 
949
        os.chmod(wireless_conf, 0600)
 
950
        os.chmod(wired_conf, 0600)
 
951
 
 
952
        # Make root own them
 
953
        print "chowning configuration files root:root..."
 
954
        os.chown(app_conf.get_config(), 0, 0)
 
955
        os.chown(wireless_conf, 0, 0)
 
956
        os.chown(wired_conf, 0, 0)
 
957
 
 
958
        print "Using wireless interface..." + self.GetWirelessInterface()
 
959
        print "Using wired interface..." + self.GetWiredInterface()
 
960
 
 
961
##############################
 
962
###### Wireless Daemon #######
 
963
##############################
 
964
 
 
965
class WirelessDaemon(dbus.service.Object):
 
966
    """ DBus interface for wireless connection operations. """
 
967
    def __init__(self, bus_name, daemon, wifi=None, debug=False):
 
968
        """ Intitialize the wireless DBus interface. """
 
969
        dbus.service.Object.__init__(self, bus_name=bus_name,
 
970
                                     object_path='/org/wicd/daemon/wireless')
 
971
        self.hidden_essid = None
 
972
        self.daemon = daemon
 
973
        self.wifi = wifi
 
974
        self._debug_mode = debug
 
975
        self._scanning = False
 
976
        self.LastScan = []
 
977
        self.config = ConfigManager(os.path.join(wpath.etc, 
 
978
                                                 "wireless-settings.conf"),
 
979
                                    debug=debug)
 
980
 
 
981
    def get_debug_mode(self):
 
982
        return self._debug_mode
 
983
    def set_debug_mode(self, mode):
 
984
        self._debug_mode = mode
 
985
        self.config.debug = mode
 
986
    debug_mode = property(get_debug_mode, set_debug_mode)
 
987
 
 
988
    @dbus.service.method('org.wicd.daemon.wireless')
 
989
    def SetHiddenNetworkESSID(self, essid):
 
990
        """ Sets the ESSID of a hidden network for use with Scan(). """
 
991
        self.hidden_essid = str(misc.Noneify(essid))
 
992
 
 
993
    @dbus.service.method('org.wicd.daemon.wireless')
 
994
    def Scan(self, sync=False):
 
995
        """ Scan for wireless networks.
 
996
 
 
997
        Scans for wireless networks, optionally using a (hidden) essid
 
998
        set with SetHiddenNetworkESSID.
 
999
 
 
1000
        The sync keyword argument specifies whether the scan should
 
1001
        be done synchronously.
 
1002
 
 
1003
        """
 
1004
        if self._scanning:
 
1005
            if self.debug_mode:
 
1006
                print "scan already in progress, skipping"
 
1007
            return False
 
1008
        if self.debug_mode:
 
1009
            print 'scanning start'
 
1010
        self.SendStartScanSignal()
 
1011
        if sync:
 
1012
            self._sync_scan()
 
1013
        else:
 
1014
            self._async_scan()
 
1015
        return True
 
1016
 
 
1017
    @misc.threaded
 
1018
    def _async_scan(self):
 
1019
        """ Run a scan in its own thread. """
 
1020
        self._sync_scan()
 
1021
 
 
1022
    def _sync_scan(self):
 
1023
        """ Run a scan and send a signal when its finished. """
 
1024
        scan = self.wifi.Scan(str(self.hidden_essid))
 
1025
        self.LastScan = scan
 
1026
        if self.debug_mode:
 
1027
            print 'scanning done'
 
1028
            print 'found ' + str(len(scan)) + ' networks:'
 
1029
        for i, network in enumerate(scan):
 
1030
            self.ReadWirelessNetworkProfile(i)
 
1031
        self.SendEndScanSignal()
 
1032
 
 
1033
    @dbus.service.method('org.wicd.daemon.wireless')
 
1034
    def GetIwconfig(self):
 
1035
        """ Calls and returns the output of iwconfig"""
 
1036
        return misc.to_unicode(self.wifi.GetIwconfig())
 
1037
 
 
1038
    @dbus.service.method('org.wicd.daemon.wireless')
 
1039
    def GetNumberOfNetworks(self):
 
1040
        """ Returns number of networks. """
 
1041
        return len(self.LastScan)
 
1042
 
 
1043
    @dbus.service.method('org.wicd.daemon.wireless')
 
1044
    def GetApBssid(self):
 
1045
        """ Gets the MAC address for the active network. """
 
1046
        return self.wifi.GetBSSID()
 
1047
 
 
1048
    @dbus.service.method('org.wicd.daemon.wireless')
 
1049
    def GetCurrentBitrate(self, iwconfig):
 
1050
        """ Returns the current bitrate for the active network. """
 
1051
        return self.wifi.GetCurrentBitrate(iwconfig)
 
1052
 
 
1053
    @dbus.service.method('org.wicd.daemon.wireless')
 
1054
    def GetOperationalMode(self, iwconfig):
 
1055
        """ Returns the operational mode for the iwconfig parameter """
 
1056
        return misc.to_unicode(self.wifi.GetOperationalMode(iwconfig))
 
1057
 
 
1058
    @dbus.service.method('org.wicd.daemon.wireless')
 
1059
    def GetAvailableAuthMethods(self, iwlistauth):
 
1060
        """ Returns the operational mode for the iwlistauth parameter """
 
1061
        return misc.to_unicode(self.wifi.GetAvailableAuthMethods(iwlistauth))
 
1062
 
 
1063
    @dbus.service.method('org.wicd.daemon.wireless')
 
1064
    def CreateAdHocNetwork(self, essid, channel, ip, enctype, key, encused,
 
1065
                           ics):
 
1066
        """ Creates an ad-hoc network using user inputted settings. """
 
1067
        self.wifi.CreateAdHocNetwork(essid, channel, ip, enctype, key, encused)
 
1068
 
 
1069
    @dbus.service.method('org.wicd.daemon.wireless')
 
1070
    def GetKillSwitchEnabled(self):
 
1071
        """ Returns true if kill switch is pressed. """
 
1072
        status = self.wifi.GetKillSwitchStatus()
 
1073
        return status
 
1074
 
 
1075
    @dbus.service.method('org.wicd.daemon.wireless')
 
1076
    def GetWirelessProperty(self, networkid, property):
 
1077
        """ Retrieves wireless property from the network specified """
 
1078
        try:
 
1079
            value = self.LastScan[networkid].get(property)
 
1080
        except IndexError:
 
1081
            return ""
 
1082
        value = misc.to_unicode(value)
 
1083
        return value
 
1084
 
 
1085
    @dbus.service.method('org.wicd.daemon.wireless')
 
1086
    def SetWirelessProperty(self, netid, prop, value):
 
1087
        """ Sets property to value in network specified. """
 
1088
        # We don't write script settings here.
 
1089
        if (prop.strip()).endswith("script"):
 
1090
            print "Setting script properties through the daemon is not" \
 
1091
                  + " permitted."
 
1092
            return False
 
1093
        self.LastScan[netid][prop] = misc.to_unicode(misc.Noneify(value))
 
1094
 
 
1095
    @dbus.service.method('org.wicd.daemon.wireless')
 
1096
    def DetectWirelessInterface(self):
 
1097
        """ Returns an automatically detected wireless interface. """
 
1098
        iface = self.wifi.DetectWirelessInterface()
 
1099
        if iface:
 
1100
            print 'Automatically detected wireless interface ' + iface
 
1101
        else:
 
1102
            print "Couldn't detect a wireless interface."
 
1103
        return str(iface)
 
1104
 
 
1105
    @dbus.service.method('org.wicd.daemon.wireless')
 
1106
    def DisconnectWireless(self):
 
1107
        """ Disconnects the wireless network. """
 
1108
        self.wifi.Disconnect()
 
1109
        self.daemon.UpdateState()
 
1110
 
 
1111
    @dbus.service.method('org.wicd.daemon.wireless')
 
1112
    def IsWirelessUp(self):
 
1113
        """ Returns a boolean specifying if wireless is up or down. """
 
1114
        return self.wifi.IsUp()
 
1115
 
 
1116
    @dbus.service.method('org.wicd.daemon.wireless')
 
1117
    def GetCurrentSignalStrength(self, iwconfig=None):
 
1118
        """ Returns the current signal strength. """
 
1119
        try:
 
1120
            strength = int(self.wifi.GetSignalStrength(iwconfig))
 
1121
        except TypeError:
 
1122
            strength = 0
 
1123
        return strength
 
1124
 
 
1125
    @dbus.service.method('org.wicd.daemon.wireless')
 
1126
    def GetCurrentDBMStrength(self, iwconfig=None):
 
1127
        """ Returns the current dbm signal strength. """
 
1128
        try:
 
1129
            dbm_strength = int(self.wifi.GetDBMStrength(iwconfig))
 
1130
        except:
 
1131
            dbm_strength = 0
 
1132
        return dbm_strength
 
1133
 
 
1134
    @dbus.service.method('org.wicd.daemon.wireless')
 
1135
    def GetCurrentNetwork(self, iwconfig=None):
 
1136
        """ Returns the current network. """
 
1137
        current_network = str(self.wifi.GetCurrentNetwork(iwconfig))
 
1138
        return current_network
 
1139
 
 
1140
    @dbus.service.method('org.wicd.daemon.wireless')
 
1141
    def GetCurrentNetworkID(self, iwconfig=None):
 
1142
        """ Returns the id of the current network, or -1 if its not found. """
 
1143
        currentESSID = self.GetCurrentNetwork(iwconfig)
 
1144
        for x in xrange(0, len(self.LastScan)):
 
1145
            if self.LastScan[x]['essid'] == currentESSID:
 
1146
                return x
 
1147
        if self.debug_mode:
 
1148
            print 'GetCurrentNetworkID: Returning -1, current network not found'
 
1149
        return -1
 
1150
 
 
1151
    @dbus.service.method('org.wicd.daemon.wireless')
 
1152
    def EnableWirelessInterface(self):
 
1153
        """ Calls a method to enable the wireless interface. """
 
1154
        result = self.wifi.EnableInterface()
 
1155
        return result
 
1156
 
 
1157
    @dbus.service.method('org.wicd.daemon.wireless')
 
1158
    def DisableWirelessInterface(self):
 
1159
        """ Calls a method to disable the wireless interface. """
 
1160
        result = self.wifi.DisableInterface()
 
1161
        return result
 
1162
 
 
1163
    @dbus.service.method('org.wicd.daemon.wireless')
 
1164
    def ConnectWireless(self, id):
 
1165
        """ Connects the the wireless network specified by i"""
 
1166
        self.SaveWirelessNetworkProfile(id)
 
1167
        # Will returned instantly, that way we don't hold up dbus.
 
1168
        # CheckIfWirelessConnecting can be used to test if the connection
 
1169
        # is done.
 
1170
        self.wifi.before_script = self.GetWirelessProperty(id, 'beforescript')
 
1171
        self.wifi.after_script = self.GetWirelessProperty(id, 'afterscript')
 
1172
        self.wifi.pre_disconnect_script = self.GetWirelessProperty(id,
 
1173
                                                               'predisconnectscript')
 
1174
        self.wifi.post_disconnect_script = self.GetWirelessProperty(id,
 
1175
                                                               'postdisconnectscript')
 
1176
        print 'Connecting to wireless network ' + str(self.LastScan[id]['essid'])
 
1177
        # disconnect to make sure that scripts are run
 
1178
        self.wifi.Disconnect()
 
1179
        self.daemon.wired_bus.wired.Disconnect()
 
1180
        self.daemon.SetForcedDisconnect(False)
 
1181
        conthread = self.wifi.Connect(self.LastScan[id], debug=self.debug_mode)
 
1182
        self.daemon.UpdateState()
 
1183
 
 
1184
    @dbus.service.method('org.wicd.daemon.wireless')
 
1185
    def CheckIfWirelessConnecting(self):
 
1186
        """Returns True if wireless interface is connecting, otherwise False."""
 
1187
        if self.wifi.connecting_thread:
 
1188
            return self.wifi.connecting_thread.is_connecting
 
1189
        else:
 
1190
            return False
 
1191
 
 
1192
    @dbus.service.method('org.wicd.daemon.wireless')
 
1193
    def GetWirelessIP(self, ifconfig=""):
 
1194
        """ Returns the IP associated with the wireless interface. """
 
1195
        ip = self.wifi.GetIP(ifconfig)
 
1196
        return ip
 
1197
 
 
1198
    @dbus.service.method('org.wicd.daemon.wireless')
 
1199
    def CheckWirelessConnectingMessage(self):
 
1200
        """ Returns the wireless interface's status message. """
 
1201
        if not self.wifi.connecting_thread == None:
 
1202
            stat = self.wifi.connecting_thread.GetStatus()
 
1203
            return stat
 
1204
        else:
 
1205
            return False
 
1206
 
 
1207
    @dbus.service.method('org.wicd.daemon.wireless')
 
1208
    def ReadWirelessNetworkProfile(self, id):
 
1209
        """ Reads in wireless profile as the active network """
 
1210
        cur_network = self.LastScan[id]
 
1211
        essid_key = "essid:%s" % cur_network["essid"]
 
1212
        bssid_key = cur_network["bssid"]
 
1213
 
 
1214
        if self.config.get(essid_key, 'use_settings_globally'):
 
1215
            section = essid_key
 
1216
        elif self.config.has_section(bssid_key):
 
1217
            section = bssid_key
 
1218
        else:
 
1219
            cur_network["has_profile"] = False
 
1220
            return "500: Profile Not Found"
 
1221
 
 
1222
        cur_network["has_profile"] = True
 
1223
 
 
1224
        for x in self.config.options(section):
 
1225
            if not cur_network.has_key(x) or x.endswith("script"):
 
1226
                cur_network[x] = misc.Noneify(self.config.get(section, x))
 
1227
        for option in ['use_static_dns', 'use_global_dns', 'encryption',
 
1228
                       'use_settings_globally']:
 
1229
            cur_network[option] = bool(cur_network.get(option))
 
1230
        # Read the essid because we need to name those hidden
 
1231
        # wireless networks now - but only read it if it is hidden.
 
1232
        if cur_network["hidden"]:
 
1233
            # check if there is an essid in the config file
 
1234
            # if there isn't, .get( will return None
 
1235
            stored_essid = self.config.get(section, 'essid')
 
1236
            if stored_essid:
 
1237
                # set the current network's ESSID to the stored one
 
1238
                cur_network['essid'] = stored_essid
 
1239
 
 
1240
    @dbus.service.method('org.wicd.daemon.wireless')
 
1241
    def SaveWirelessNetworkProfile(self, id):
 
1242
        """ Writes a wireless profile to disk. """
 
1243
        def write_script_ent(prof, script):
 
1244
            if not self.config.has_option(prof, script):
 
1245
                self.config.set(prof, script, None)
 
1246
 
 
1247
        cur_network = self.LastScan[id]
 
1248
        bssid_key = cur_network["bssid"]
 
1249
        essid_key = "essid:%s" % cur_network["essid"]
 
1250
 
 
1251
        self.config.remove_section(bssid_key)
 
1252
        self.config.add_section(bssid_key)
 
1253
 
 
1254
        # We want to write the essid in addition to bssid
 
1255
        # sections if global settings are enabled.
 
1256
        self.config.remove_section(essid_key)
 
1257
        if cur_network.get("use_settings_globally", False):
 
1258
            self.config.add_section(essid_key)
 
1259
 
 
1260
        for x in cur_network:
 
1261
            self.config.set(bssid_key, x, cur_network[x])
 
1262
            if cur_network.get("use_settings_globally", False):
 
1263
                self.config.set(essid_key, x, cur_network[x])
 
1264
 
 
1265
        write_script_ent(bssid_key, "beforescript")
 
1266
        write_script_ent(bssid_key, "afterscript")
 
1267
        write_script_ent(bssid_key, "predisconnectscript")
 
1268
        write_script_ent(bssid_key, "postdisconnectscript")
 
1269
 
 
1270
        if cur_network.get("use_settings_globally", False):
 
1271
            write_script_ent(essid_key, "beforescript")
 
1272
            write_script_ent(essid_key, "afterscript")
 
1273
            write_script_ent(essid_key, "predisconnectscript")
 
1274
            write_script_ent(essid_key, "postdisconnectscript")
 
1275
 
 
1276
        self.config.write()
 
1277
 
 
1278
    @dbus.service.method('org.wicd.daemon.wireless')
 
1279
    def SaveWirelessNetworkProperty(self, id, option):
 
1280
        """ Writes a particular wireless property to disk. """
 
1281
        if (option.strip()).endswith("script"):
 
1282
            print 'You cannot save script information to disk through ' + \
 
1283
                  'the daemon.'
 
1284
            return
 
1285
        config = self.config
 
1286
        cur_network = self.LastScan[id]
 
1287
        essid_key = "essid:" + cur_network["essid"]
 
1288
 
 
1289
        config.set(cur_network["bssid"], option, str(cur_network[option]))
 
1290
 
 
1291
        # Write the global section as well, if required.
 
1292
        if config.get(essid_key, 'use_settings_globally'):
 
1293
            config.set(essid_key, option, str(cur_network[option]))
 
1294
        config.write()
 
1295
 
 
1296
    @dbus.service.method('org.wicd.daemon.wireless')
 
1297
    def RemoveGlobalEssidEntry(self, networkid):
 
1298
        """ Removes the global entry for the networkid provided. """
 
1299
        essid_key = "essid:" + str(self.LastScan[networkid])
 
1300
        self.config.remove_section(essid_key)
 
1301
 
 
1302
    @dbus.service.method('org.wicd.daemon.wireless')
 
1303
    def GetWpaSupplicantDrivers(self):
 
1304
        """ Returns all valid wpa_supplicant drivers. """
 
1305
        return self.wifi.GetWpaSupplicantDrivers()
 
1306
 
 
1307
    @dbus.service.method('org.wicd.daemon.wireless')
 
1308
    def ReloadConfig(self):
 
1309
        """ Reloads the active config file. """
 
1310
        self.config.reload()
 
1311
 
 
1312
    @dbus.service.method('org.wicd.daemon.wireless')
 
1313
    def GetWirelessInterfaces(self):
 
1314
        ''' Returns a list of wireless interfaces on the system. '''
 
1315
        return wnettools.GetWirelessInterfaces()
 
1316
 
 
1317
    @dbus.service.signal(dbus_interface='org.wicd.daemon.wireless', signature='')
 
1318
    def SendStartScanSignal(self):
 
1319
        """ Emits a signal announcing a scan has started. """
 
1320
        self._scanning = True
 
1321
 
 
1322
    @dbus.service.signal(dbus_interface='org.wicd.daemon.wireless', signature='')
 
1323
    def SendEndScanSignal(self):
 
1324
        """ Emits a signal announcing a scan has finished. """
 
1325
        self._scanning = False
 
1326
 
 
1327
    def _wireless_autoconnect(self, fresh=True):
 
1328
        """ Attempts to autoconnect to a wireless network. """
 
1329
        print "No wired connection present, attempting to autoconnect " + \
 
1330
              "to wireless network"
 
1331
        if self.wifi.wireless_interface is None:
 
1332
            print 'Autoconnect failed because wireless interface returned None'
 
1333
            return
 
1334
        if fresh:
 
1335
            self.Scan(sync=True)
 
1336
 
 
1337
        for x, network in enumerate(self.LastScan):
 
1338
            if bool(network["has_profile"]):
 
1339
                if self.debug_mode:
 
1340
                    print network["essid"] + ' has profile'
 
1341
                if bool(network.get('automatic')):
 
1342
                    print 'trying to automatically connect to...' + \
 
1343
                          network["essid"]
 
1344
                    self.ConnectWireless(x)
 
1345
                    time.sleep(1)
 
1346
                    return
 
1347
        print "Unable to autoconnect, you'll have to manually connect"
 
1348
 
 
1349
###########################
 
1350
###### Wired Daemon #######
 
1351
###########################
 
1352
 
 
1353
class WiredDaemon(dbus.service.Object):
 
1354
    """ DBus interface for wired connection operations. """
 
1355
    def __init__(self, bus_name, daemon, wired=None, debug=False):
 
1356
        """ Intitialize the wireless DBus interface. """
 
1357
        dbus.service.Object.__init__(self, bus_name=bus_name,
 
1358
                                     object_path="/org/wicd/daemon/wired")
 
1359
        self.daemon = daemon
 
1360
        self.wired = wired
 
1361
        self._debug_mode = debug
 
1362
        self._cur_wired_prof_name = ""
 
1363
        self.WiredNetwork = {}
 
1364
        self.config = ConfigManager(os.path.join(wpath.etc,
 
1365
                                                 "wired-settings.conf"), 
 
1366
                                    debug=debug)
 
1367
 
 
1368
    def get_debug_mode(self):
 
1369
        return self._debug_mode
 
1370
    def set_debug_mode(self, mode):
 
1371
        self._debug_mode = mode
 
1372
        self.config.debug = mode
 
1373
    debug_mode = property(get_debug_mode, set_debug_mode)
 
1374
 
 
1375
    @dbus.service.method('org.wicd.daemon.wired')
 
1376
    def GetWiredIP(self, ifconfig=""):
 
1377
        """ Returns the wired interface's ip address. """
 
1378
        ip = self.wired.GetIP(ifconfig)
 
1379
        return ip
 
1380
 
 
1381
    @dbus.service.method('org.wicd.daemon.wired')
 
1382
    def CheckIfWiredConnecting(self):
 
1383
        """ Returns True if wired interface is connecting, otherwise False. """
 
1384
        if self.wired.connecting_thread:
 
1385
            return self.wired.connecting_thread.is_connecting
 
1386
        else:
 
1387
            return False
 
1388
 
 
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 self.wired.connecting_thread.GetStatus()
 
1394
        else:
 
1395
            return False
 
1396
 
 
1397
    @dbus.service.method('org.wicd.daemon.wired')
 
1398
    def DetectWiredInterface(self):
 
1399
        """ Returns an automatically detected wireless interface. """
 
1400
        iface = self.wired.DetectWiredInterface()
 
1401
        if iface:
 
1402
            print 'automatically detected wired interface ' + str(iface)
 
1403
        else:
 
1404
            print "Couldn't detect a wired interface."
 
1405
        return str(iface)
 
1406
 
 
1407
    @dbus.service.method('org.wicd.daemon.wired')
 
1408
    def SetWiredProperty(self, property, value):
 
1409
        """ Sets the given property to the given value. """
 
1410
        if self.WiredNetwork:
 
1411
            if (property.strip()).endswith("script"):
 
1412
                print "Setting script properties through the daemon" \
 
1413
                      + " is not permitted."
 
1414
                return False
 
1415
            self.WiredNetwork[property] = misc.to_unicode(misc.Noneify(value))
 
1416
            return True
 
1417
        else:
 
1418
            print 'SetWiredProperty: WiredNetwork does not exist'
 
1419
            return False
 
1420
 
 
1421
    @dbus.service.method('org.wicd.daemon.wired')
 
1422
    def GetWiredProperty(self, property):
 
1423
        """ Returns the requested wired property. """
 
1424
        if self.WiredNetwork:
 
1425
            value = self.WiredNetwork.get(property)
 
1426
            return value
 
1427
        else:
 
1428
            print 'GetWiredProperty: WiredNetwork does not exist'
 
1429
            return False
 
1430
 
 
1431
    @dbus.service.method('org.wicd.daemon.wired')
 
1432
    def HasWiredDriver(self):
 
1433
        """ Returns True if a driver is associated with this interface. """
 
1434
        if self.wired.driver:
 
1435
            return True
 
1436
        else:
 
1437
            return False
 
1438
 
 
1439
    @dbus.service.method('org.wicd.daemon.wired')
 
1440
    def DisconnectWired(self):
 
1441
        """ Disconnects the wired network. """
 
1442
        self.wired.Disconnect()
 
1443
        self.daemon.UpdateState()
 
1444
 
 
1445
    @dbus.service.method('org.wicd.daemon.wired')
 
1446
    def CheckPluggedIn(self):
 
1447
        """ Returns True if a ethernet cable is present, False otherwise. """
 
1448
        if self.wired.wired_interface and self.wired.wired_interface != "None":
 
1449
            return self.wired.CheckPluggedIn()
 
1450
        else:
 
1451
            return None
 
1452
 
 
1453
    @dbus.service.method('org.wicd.daemon.wired')
 
1454
    def IsWiredUp(self):
 
1455
        """ Returns a boolean specifying if wired iface is up or down. """
 
1456
        return self.wired.IsUp()
 
1457
 
 
1458
    @dbus.service.method('org.wicd.daemon.wired')
 
1459
    def EnableWiredInterface(self):
 
1460
        """ Calls a method to enable the wired interface. """           
 
1461
        return self.wired.EnableInterface()
 
1462
 
 
1463
    @dbus.service.method('org.wicd.daemon.wired')
 
1464
    def DisableWiredInterface(self):
 
1465
        """ Calls a method to disable the wired interface. """
 
1466
        return self.wired.DisableInterface()
 
1467
 
 
1468
    @dbus.service.method('org.wicd.daemon.wired')
 
1469
    def ConnectWired(self):
 
1470
        """ Connects to a wired network. """
 
1471
        self.wired.before_script = self.GetWiredProperty("beforescript")
 
1472
        self.wired.after_script = self.GetWiredProperty("afterscript")
 
1473
        self.wired.pre_disconnect_script = self.GetWiredProperty("predisconnectscript")
 
1474
        self.wired.post_disconnect_script = self.GetWiredProperty("postdisconnectscript")
 
1475
        self.daemon.wireless_bus.wifi.Disconnect()
 
1476
        # make sure disconnect scripts are run
 
1477
        self.wired.Disconnect()
 
1478
        self.daemon.SetForcedDisconnect(False)
 
1479
        self.UnsetWiredLastUsed()
 
1480
        self.config.set(self._cur_wired_prof_name, "lastused", True, write=True)
 
1481
        self.wired.Connect(self.WiredNetwork, debug=self.debug_mode)
 
1482
        self.daemon.UpdateState()
 
1483
 
 
1484
    @dbus.service.method('org.wicd.daemon.wired')
 
1485
    def CreateWiredNetworkProfile(self, profilename, default=False):
 
1486
        """ Creates a wired network profile. """
 
1487
        if not profilename:
 
1488
            return False
 
1489
        profilename = misc.to_unicode(profilename)
 
1490
        print "Creating wired profile for " + profilename
 
1491
        if self.config.has_section(profilename):
 
1492
            return False
 
1493
 
 
1494
        for option in ["ip", "broadcast", "netmask", "gateway", "search_domain", 
 
1495
                       "dns_domain", "dns1", "dns2", "dns3", "beforescript", 
 
1496
                       "afterscript", "predisconnectscript",
 
1497
                       "postdisconnectscript"]:
 
1498
            self.config.set(profilename, option, None)
 
1499
        self.config.set(profilename, "default", default)
 
1500
        self.config.set(profilename,"dhcphostname",os.uname()[1])
 
1501
        self.config.write()
 
1502
        return True
 
1503
 
 
1504
    @dbus.service.method('org.wicd.daemon.wired')
 
1505
    def UnsetWiredLastUsed(self):
 
1506
        """ Finds the previous lastused network, and sets lastused to False. """
 
1507
        profileList = self.config.sections()
 
1508
        for profile in profileList:
 
1509
            if misc.to_bool(self.config.get(profile, "lastused")):
 
1510
                self.config.set(profile, "lastused", False, write=True)
 
1511
 
 
1512
    @dbus.service.method('org.wicd.daemon.wired')
 
1513
    def UnsetWiredDefault(self):
 
1514
        """ Unsets the default option in the current default wired profile. """
 
1515
        profileList = self.config.sections()
 
1516
        for profile in profileList:
 
1517
            if misc.to_bool(self.config.get(profile, "default")):
 
1518
                self.config.set(profile, "default", False, write=True)
 
1519
 
 
1520
    @dbus.service.method('org.wicd.daemon.wired')
 
1521
    def GetDefaultWiredNetwork(self):
 
1522
        """ Returns the current default wired network. """
 
1523
        profileList = self.config.sections()
 
1524
        for profile in profileList:
 
1525
            if misc.to_bool(self.config.get(profile, "default")):
 
1526
                return profile
 
1527
        return None
 
1528
 
 
1529
    @dbus.service.method('org.wicd.daemon.wired')
 
1530
    def GetLastUsedWiredNetwork(self):
 
1531
        """ Returns the profile of the last used wired network. """
 
1532
        profileList = self.config.sections()
 
1533
        for profile in profileList:
 
1534
            if misc.to_bool(self.config.get(profile, "lastused")):
 
1535
                return profile
 
1536
        return None
 
1537
 
 
1538
    @dbus.service.method('org.wicd.daemon.wired')
 
1539
    def DeleteWiredNetworkProfile(self, profilename):
 
1540
        """ Deletes a wired network profile. """
 
1541
        profilename = misc.to_unicode(profilename)
 
1542
        print "Deleting wired profile for " + str(profilename)
 
1543
        self.config.remove_section(profilename)
 
1544
        self.config.write()
 
1545
 
 
1546
    @dbus.service.method('org.wicd.daemon.wired')
 
1547
    def SaveWiredNetworkProfile(self, profilename):
 
1548
        """ Writes a wired network profile to disk. """
 
1549
        def write_script_ent(prof, script):
 
1550
            if not self.config.has_option(prof, script):
 
1551
                self.config.set(prof, script, None)
 
1552
 
 
1553
        profilename = profilename.strip()
 
1554
        if not profilename:
 
1555
            self.config.write()
 
1556
            print "Warning: Bad wired profile name given, ignoring."
 
1557
            return "500: Bad Profile name"
 
1558
        if self.debug_mode:
 
1559
            print "saving wired profile %s" % profilename
 
1560
        profilename = misc.to_unicode(profilename)
 
1561
        self.config.remove_section(profilename)
 
1562
        self.config.add_section(profilename)
 
1563
        for x in self.WiredNetwork:
 
1564
            self.config.set(profilename, x, self.WiredNetwork[x])
 
1565
 
 
1566
        write_script_ent(profilename, "beforescript")
 
1567
        write_script_ent(profilename, "afterscript")
 
1568
        write_script_ent(profilename, "predisconnectscript")
 
1569
        write_script_ent(profilename, "postdisconnectscript")
 
1570
        self.config.write()
 
1571
        return "100: Profile Written"
 
1572
 
 
1573
    @dbus.service.method('org.wicd.daemon.wired')
 
1574
    def ReadWiredNetworkProfile(self, profilename):
 
1575
        """ Reads a wired network profile in as the currently active profile """
 
1576
        profile = {}
 
1577
        profilename = misc.to_unicode(profilename)
 
1578
        if self.config.has_section(profilename):
 
1579
            if self.debug_mode:
 
1580
                print "Reading wired profile %s" % profilename
 
1581
            for x in self.config.options(profilename):
 
1582
                profile[x] = misc.Noneify(self.config.get(profilename, x))
 
1583
            profile['use_global_dns'] = bool(profile.get('use_global_dns'))
 
1584
            profile['use_static_dns'] = bool(profile.get('use_static_dns'))
 
1585
            profile['profilename'] = profilename
 
1586
            self.WiredNetwork = profile
 
1587
            self._cur_wired_prof_name = profilename
 
1588
            return "100: Loaded Profile"
 
1589
        else:
 
1590
            self._cur_wired_prof_name = ""
 
1591
            self.WiredNetwork = {}
 
1592
            return "500: Profile Not Found"
 
1593
 
 
1594
    @dbus.service.method('org.wicd.daemon.wired')
 
1595
    def GetWiredProfileList(self):
 
1596
        """ Returns a list of all wired profiles in wired-settings.conf. """
 
1597
        sections = self.config.sections()
 
1598
        if not sections:
 
1599
            sections = [""]
 
1600
        return sections
 
1601
 
 
1602
    @dbus.service.method('org.wicd.daemon.wired')
 
1603
    def ReloadConfig(self):
 
1604
        """ Reloads the active config file. """
 
1605
        self.config.reload()
 
1606
 
 
1607
    @dbus.service.method('org.wicd.daemon.wired')
 
1608
    def GetWiredInterfaces(self):
 
1609
        ''' Returns a list of wireless interfaces on the system. '''
 
1610
        return wnettools.GetWiredInterfaces()
 
1611
 
 
1612
def usage():
 
1613
    print """
 
1614
wicd %s 
 
1615
wireless (and wired) connection daemon.
 
1616
 
 
1617
Arguments:
 
1618
\t-a\t--no-autoconnect\tDon't auto-scan/auto-connect.
 
1619
\t-f\t--no-daemon\tDon't daemonize (run in foreground).
 
1620
\t-e\t--no-stderr\tDon't redirect stderr.
 
1621
\t-n\t--no-poll\tDon't monitor network status.
 
1622
\t-o\t--no-stdout\tDon't redirect stdout.
 
1623
\t-h\t--help\t\tPrint this help.
 
1624
""" % (wpath.version + ' (bzr-r%s)' % wpath.revision)
 
1625
 
 
1626
def daemonize():
 
1627
    """ Disconnect from the controlling terminal.
 
1628
 
 
1629
    Fork twice, once to disconnect ourselves from the parent terminal and a
 
1630
    second time to prevent any files we open from becoming our controlling
 
1631
    terminal.
 
1632
 
 
1633
    For more info see:
 
1634
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
 
1635
 
 
1636
    """
 
1637
    # Fork the first time to disconnect from the parent terminal and
 
1638
    # exit the parent process.
 
1639
    try:
 
1640
        pid = os.fork()
 
1641
        if pid > 0:
 
1642
            sys.exit(0)
 
1643
    except OSError, e:
 
1644
        print >> sys.stderr, "Fork #1 failed: %d (%s)" % (e.errno, e.strerror)
 
1645
        sys.exit(1)
 
1646
 
 
1647
    # Decouple from parent environment to stop us from being a zombie.
 
1648
    os.setsid()
 
1649
 
 
1650
    # Fork the second time to prevent us from opening a file that will
 
1651
    # become our controlling terminal.
 
1652
    try:
 
1653
        pid = os.fork()
 
1654
        if pid > 0:
 
1655
            dirname = os.path.dirname(wpath.pidfile)
 
1656
            if not os.path.exists(dirname):
 
1657
                os.makedirs(dirname)
 
1658
            pidfile = open(wpath.pidfile, 'w')
 
1659
            pidfile.write(str(pid) + '\n')
 
1660
            pidfile.close()
 
1661
            sys.exit(0)
 
1662
        else:
 
1663
            os.umask(0)
 
1664
            os.chdir('/')
 
1665
    except OSError, e:
 
1666
        print >> sys.stderr, "Fork #2 failed: %d (%s)" % (e.errno, e.strerror)
 
1667
        sys.exit(1)
 
1668
 
 
1669
    sys.stdin.close()
 
1670
    sys.stdout.close()
 
1671
    sys.stderr.close()
 
1672
 
 
1673
    try:
 
1674
        maxfd = os.sysconf("SC_OPEN_MAX")
 
1675
    except (AttributeError, ValueError):
 
1676
        maxfd = 1024
 
1677
       
 
1678
    for fd in range(0, maxfd):
 
1679
        try:
 
1680
            os.close(fd)
 
1681
        except OSError:
 
1682
            pass
 
1683
 
 
1684
    os.open(os.devnull, os.O_RDWR)
 
1685
 
 
1686
    # Duplicate standard input to standard output and standard error.
 
1687
    os.dup2(0, 1)
 
1688
    os.dup2(0, 2)
 
1689
 
 
1690
 
 
1691
def main(argv):
 
1692
    """ The main daemon program.
 
1693
 
 
1694
    Keyword arguments:
 
1695
    argv -- The arguments passed to the script.
 
1696
 
 
1697
    """
 
1698
    # back up resolv.conf before we do anything else
 
1699
    try:
 
1700
        backup_location = wpath.varlib + 'resolv.conf.orig'
 
1701
        # don't back up if .orig exists, probably there cause
 
1702
        # wicd exploded
 
1703
        if not os.path.exists(backup_location):
 
1704
            shutil.copy2('/etc/resolv.conf', backup_location)
 
1705
    except IOError:
 
1706
        print 'error backing up resolv.conf'
 
1707
 
 
1708
    do_daemonize = True
 
1709
    redirect_stderr = True
 
1710
    redirect_stdout = True
 
1711
    auto_connect = True
 
1712
    kill = False
 
1713
 
 
1714
    try:
 
1715
        opts, args = getopt.getopt(sys.argv[1:], 'fenoahk',
 
1716
                                   ['help', 'no-daemon', 'no-poll', 'no-stderr', 'no-stdout',
 
1717
                                    'no-autoconnect', 'kill'])
 
1718
    except getopt.GetoptError:
 
1719
        # Print help information and exit
 
1720
        usage()
 
1721
        sys.exit(2)
 
1722
 
 
1723
    no_poll = False
 
1724
    for o, a in opts:
 
1725
        if o in ('-h', '--help'):
 
1726
            usage()
 
1727
            sys.exit()
 
1728
        if o in ('-e', '--no-stderr'):
 
1729
            redirect_stderr = False
 
1730
        if o in ('-o', '--no-stdout'):
 
1731
            redirect_stdout = False
 
1732
        if o in ('-f', '--no-daemon'):
 
1733
            do_daemonize = False
 
1734
        if o in ('-a', '--no-autoconnect'):
 
1735
            auto_connect = False
 
1736
        if o in ('-n', '--no-poll'):
 
1737
            no_poll = True
 
1738
        if o in ('-k', '--kill'):
 
1739
                kill = True     
 
1740
 
 
1741
    if kill:
 
1742
        try:
 
1743
            f = open(wpath.pidfile)
 
1744
        except:
 
1745
            #print >> sys.stderr, "No wicd instance active, aborting."
 
1746
            sys.exit(1)
 
1747
 
 
1748
        # restore resolv.conf on quit
 
1749
        try:
 
1750
            shutil.move(wpath.varlib + 'resolv.conf.orig', '/etc/resolv.conf')
 
1751
        except IOError:
 
1752
            print 'error restoring resolv.conf'
 
1753
 
 
1754
        # connect to dbus, trigger a disconnect, then knock out the daemon
 
1755
        from wicd import dbusmanager
 
1756
        bus = dbusmanager.connect_to_dbus()
 
1757
        dbus_ifaces = dbusmanager.get_dbus_ifaces()
 
1758
        dbus_ifaces['daemon'].Disconnect()
 
1759
        pid = int(f.readline())
 
1760
        f.close()
 
1761
        os.kill(pid,signal.SIGTERM)
 
1762
 
 
1763
        # quit, this should be the only option specified
 
1764
        sys.exit(0)
 
1765
 
 
1766
    if not os.path.exists(wpath.networks):
 
1767
        os.makedirs(wpath.networks)
 
1768
   
 
1769
    if do_daemonize: daemonize()
 
1770
 
 
1771
    if redirect_stderr or redirect_stdout:
 
1772
        logpath = os.path.join(wpath.log, 'wicd.log')
 
1773
        if not os.path.exists(wpath.log):
 
1774
            os.makedirs(wpath.log)
 
1775
            os.chmod(wpath.log, 0755)
 
1776
        output = ManagedStdio(logpath)
 
1777
        if os.path.exists(logpath):
 
1778
            try:
 
1779
                os.chmod(logpath, int(wpath.log_perms,8))
 
1780
            except:
 
1781
                print 'unable to chmod log file to %s' % wpath.log_perms
 
1782
 
 
1783
            try:
 
1784
                if wpath.log_group:
 
1785
                    import grp
 
1786
                    group = grp.getgrnam(wpath.log_group)
 
1787
                    os.chown(logpath, 0, group[2])
 
1788
            except:
 
1789
                print 'unable to chown log file to %s' % group[2]
 
1790
 
 
1791
    if redirect_stdout: sys.stdout = output
 
1792
    if redirect_stderr: sys.stderr = output
 
1793
 
 
1794
    print '---------------------------'
 
1795
    print 'wicd initializing...'
 
1796
    print '---------------------------'
 
1797
 
 
1798
    print 'wicd is version', wpath.version, wpath.revision
 
1799
 
 
1800
    # Open the DBUS session
 
1801
    bus = dbus.SystemBus()
 
1802
    wicd_bus = dbus.service.BusName('org.wicd.daemon', bus=bus)
 
1803
    daemon = WicdDaemon(wicd_bus, auto_connect=auto_connect)
 
1804
    if not no_poll:
 
1805
        child_pid = Popen([misc.find_path("python"), "-O", 
 
1806
                          os.path.join(wpath.daemon, "monitor.py")],
 
1807
                          shell=False, close_fds=True).pid
 
1808
    atexit.register(on_exit, child_pid)
 
1809
 
 
1810
    # Enter the main loop
 
1811
    mainloop = gobject.MainLoop()
 
1812
    try:
 
1813
        mainloop.run()
 
1814
    except KeyboardInterrupt:
 
1815
        pass
 
1816
    daemon.DaemonClosing()
 
1817
 
 
1818
def on_exit(child_pid):
 
1819
    """ Called when a SIGTERM is caught, kills monitor.py before exiting. """
 
1820
    if child_pid:
 
1821
        print 'Daemon going down, killing wicd-monitor...'
 
1822
        try:
 
1823
            os.kill(child_pid, signal.SIGTERM)
 
1824
        except OSError:
 
1825
            pass
 
1826
    print 'Removing PID file...'
 
1827
    if os.path.exists(wpath.pidfile):
 
1828
        os.remove(wpath.pidfile)
 
1829
    print 'Shutting down...'
 
1830
    sys.exit(0)
 
1831
 
 
1832
 
 
1833
if __name__ == '__main__':
 
1834
    if os.getuid() != 0:
 
1835
        print ("Root privileges are required for the daemon to run properly." +
 
1836
               "  Exiting.")
 
1837
        sys.exit(1)
 
1838
    gobject.threads_init()
 
1839
    main(sys.argv)