1
0
mirror of https://github.com/gryf/wicd.git synced 2025-12-20 21:08:06 +01:00

Changed misc.Run to use subprocess.Popen instead of os.popen. Also altered Run to optionally return a pipe to the command run, instead of just the output.

The output of dhclient is now parsed by wicd and used to determine why the connection failed.
All the wpa_supplicant conf files will now generate a ctrl_interface, so that they can be accessed by wpa_cli.  wpa_cli now is used by wicd to attempt to determine is wpa_supplicant authentication was successful.  This is still experimental, and might have to be tweaked to work properly.
If wicd.py is started and the daemon isn't present, it will autolaunch it by calling launchdaemon.sh, instead of asking the user to start the daemon manually.
Cleaned up some comments, formatting, etc.
Probably a couple of other little bug fixes I'm forgetting.
This commit is contained in:
imdano
2008-01-06 13:55:23 +00:00
parent 4e0dfc8e22
commit d64850dfd3
16 changed files with 354 additions and 155 deletions

View File

@@ -6,18 +6,9 @@ import dbus.service
if getattr(dbus, 'version', (0,0,0)) >= (0,41,0): if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
import dbus.glib import dbus.glib
#############
#declare our connections to our daemon.
#without them nothing useful will happen
#the daemon should be running as root
bus = dbus.SystemBus() bus = dbus.SystemBus()
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon') proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
##we don't need some of these, so I just comment them out
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
#wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
#wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired')
#config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config')
#############
print daemon.Hello() print daemon.Hello()
if daemon.CheckIfConnecting() == False: if daemon.CheckIfConnecting() == False:

View File

@@ -25,6 +25,7 @@ run as the current user.
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import os import os
import sys import sys
import gtk import gtk

View File

@@ -143,6 +143,7 @@ class ConnectionWizard(dbus.service.Object):
self.need_profile_chooser = False self.need_profile_chooser = False
self.current_interface = None self.current_interface = None
self.vpn_session = None self.vpn_session = None
self.user_init_connect = False
# Load the config file # Load the config file
self.ReadConfig() self.ReadConfig()
@@ -177,7 +178,7 @@ class ConnectionWizard(dbus.service.Object):
#micro is for everything else. #micro is for everything else.
#and micro may be anything >= 0 #and micro may be anything >= 0
#this number is effective starting wicd v1.2.0 #this number is effective starting wicd v1.2.0
version = '1.4.0' version = '1.4.2'
print 'returned version number',version print 'returned version number',version
return version return version
@@ -295,6 +296,13 @@ class ConnectionWizard(dbus.service.Object):
return int(self.debug_mode) return int(self.debug_mode)
#end function GetDebugMode #end function GetDebugMode
@dbus.service.method('org.wicd.daemon')
def Disconnect(self):
'''disconnects all networks'''
self.SetForcedDisconnect(True)
self.wifi.Disconnect()
self.wired.Disconnect()
@dbus.service.method('org.wicd.daemon') @dbus.service.method('org.wicd.daemon')
def GetSignalDisplayType(self): def GetSignalDisplayType(self):
''' Returns the signal display type ''' Returns the signal display type
@@ -381,17 +389,36 @@ class ConnectionWizard(dbus.service.Object):
@dbus.service.method('org.wicd.daemon') @dbus.service.method('org.wicd.daemon')
def GetCurrentInterface(self): def GetCurrentInterface(self):
""" Returns the active interface """
return self.current_interface return self.current_interface
@dbus.service.method('org.wicd.daemon') @dbus.service.method('org.wicd.daemon')
def SetCurrentInterface(self, iface): def SetCurrentInterface(self, iface):
""" Sets the current active interface """
self.current_interface = str(iface) self.current_interface = str(iface)
@dbus.service.method('org.wicd.daemon') @dbus.service.method('org.wicd.daemon')
def SetNeedWiredProfileChooser(self,val): def SetNeedWiredProfileChooser(self,val):
""" Sets the need_wired_profile_chooser variable.
If set to true, that alerts the wicd frontend to display the chooser,
if false the frontend will do nothing. This function is only needed
when the frontend starts up, to determine if the chooser was requested
before the frontend was launched.
"""
self.need_profile_chooser = val self.need_profile_chooser = val
#end function SetNeedWiredProfileChooser #end function SetNeedWiredProfileChooser
@dbus.service.method('org.wicd.daemon')
def SetUserInitConnect(self, val):
""" Specifies if the last connection attempt was user/cpu initiated """
self.user_init_connect = val
@dbus.service.method('org.wicd.daemon')
def GetUserInitConnect(self):
return self.user_init_connect
@dbus.service.method('org.wicd.daemon') @dbus.service.method('org.wicd.daemon')
def GetNeedWiredProfileChooser(self): def GetNeedWiredProfileChooser(self):
return bool(self.need_profile_chooser) return bool(self.need_profile_chooser)
@@ -459,13 +486,6 @@ class ConnectionWizard(dbus.service.Object):
break break
self.LastScan = master_scan self.LastScan = master_scan
@dbus.service.method('org.wicd.daemon.wireless')
def DisconnectWireless(self):
'''disconnects all wireless networks'''
self.SetForcedDisconnect(True)
self.wifi.Disconnect()
self.wired.Disconnect()
#end function DisconnectWireless
@dbus.service.method('org.wicd.daemon.wireless') @dbus.service.method('org.wicd.daemon.wireless')
def GetNumberOfNetworks(self): def GetNumberOfNetworks(self):
@@ -587,12 +607,13 @@ class ConnectionWizard(dbus.service.Object):
#end function GetCurrentNetwork #end function GetCurrentNetwork
@dbus.service.method('org.wicd.daemon.wireless') @dbus.service.method('org.wicd.daemon.wireless')
def ConnectWireless(self,id): def ConnectWireless(self,id, user_init=False):
'''connects the the wireless network specified by id''' '''connects the the wireless network specified by id'''
# Will returned instantly, that way we don't hold up dbus. # Will returned instantly, that way we don't hold up dbus.
# CheckIfWirelessConnecting can be used to test if the connection # CheckIfWirelessConnecting can be used to test if the connection
# is done. # is done.
self.SetForcedDisconnect(False) self.SetForcedDisconnect(False)
self.SetUserInitConnect(user_init)
self.wifi.before_script = self.GetWirelessProperty(id,'beforescript') self.wifi.before_script = self.GetWirelessProperty(id,'beforescript')
self.wifi.after_script = self.GetWirelessProperty(id,'afterscript') self.wifi.after_script = self.GetWirelessProperty(id,'afterscript')
self.wifi.disconnect_script = self.GetWirelessProperty(id,'disconnectscript') self.wifi.disconnect_script = self.GetWirelessProperty(id,'disconnectscript')
@@ -772,8 +793,9 @@ class ConnectionWizard(dbus.service.Object):
#end function CheckPluggedIn #end function CheckPluggedIn
@dbus.service.method('org.wicd.daemon.wired') @dbus.service.method('org.wicd.daemon.wired')
def ConnectWired(self): def ConnectWired(self, user_init=False):
'''connects to a wired network''' '''connects to a wired network'''
self.SetUserInitConnect(user_init)
self.wired.before_script = self.GetWiredProperty("beforescript") self.wired.before_script = self.GetWiredProperty("beforescript")
self.wired.after_script = self.GetWiredProperty("afterscript") self.wired.after_script = self.GetWiredProperty("afterscript")
self.wired.disconnect_script = self.GetWiredProperty("disconnectscript") self.wired.disconnect_script = self.GetWiredProperty("disconnectscript")

View File

@@ -3,6 +3,7 @@ author = Adam Blackburn
version = 2 version = 2
require username *Username password *Password pac_file *Path_To_PAC_File require username *Username password *Password pac_file *Path_To_PAC_File
----- -----
ctrl_interface=/var/run/wpa_supplicant
network={ network={
ssid="$_ESSID" ssid="$_ESSID"
scan_ssid=$_SCAN scan_ssid=$_SCAN

View File

@@ -3,6 +3,7 @@ author = Adam Blackburn
version = 1 version = 1
require username *Username password *Password require username *Username password *Password
----- -----
ctrl_interface=/var/run/wpa_supplicant
network={ network={
ssid="$_ESSID" ssid="$_ESSID"
scan_ssid=$_SCAN scan_ssid=$_SCAN

View File

@@ -3,6 +3,7 @@ author = Adam Blackburn
version = 2 version = 2
require identity *Identity password *Password require identity *Identity password *Password
----- -----
ctrl_interface=/var/run/wpa_supplicant
network={ network={
ssid="$_ESSID" ssid="$_ESSID"
proto=RSN proto=RSN

View File

@@ -3,6 +3,7 @@ author = Fralaltro
version = 1 version = 1
require identity *Identity password *Password ca_cert *Path_to_CA_Cert require identity *Identity password *Password ca_cert *Path_to_CA_Cert
----- -----
ctrl_interface=/var/run/wpa_supplicant
network={ network={
ssid="$_ESSID" ssid="$_ESSID"
scan_ssid=$_SCAN scan_ssid=$_SCAN

View File

@@ -3,6 +3,7 @@ author = Adam Blackburn
version = 1 version = 1
require anonymous_identity *Anonymous_Identity identity *Identity password *Password auth *Authentication require anonymous_identity *Anonymous_Identity identity *Identity password *Password auth *Authentication
----- -----
ctrl_interface=/var/run/wpa_supplicant
network={ network={
ssid="$_ESSID" ssid="$_ESSID"
scan_ssid=$_SCAN scan_ssid=$_SCAN

View File

@@ -3,6 +3,7 @@ author = Adam Blackburn
version = 1 version = 1
require key *Key require key *Key
----- -----
ctrl_interface=/var/run/wpa_supplicant
network={ network={
ssid="$_ESSID" ssid="$_ESSID"
scan_ssid=$_SCAN scan_ssid=$_SCAN

View File

@@ -3,6 +3,7 @@ author = Adam Blackburn
version = 1 version = 1
require key *Key require key *Key
----- -----
ctrl_interface=/var/run/wpa_supplicant
network={ network={
ssid="$_ESSID" ssid="$_ESSID"
scan_ssid=$_SCAN scan_ssid=$_SCAN

122
gui.py
View File

@@ -21,6 +21,8 @@ import os
import sys import sys
import wpath import wpath
import signal import signal
import time
if __name__ == '__main__': if __name__ == '__main__':
wpath.chdir(__file__) wpath.chdir(__file__)
try: try:
@@ -39,21 +41,24 @@ import time, os, misc, gettext, locale, gobject, dbus, dbus.service,pango
if getattr(dbus, 'version', (0,0,0)) >= (0,41,0): if getattr(dbus, 'version', (0,0,0)) >= (0,41,0):
import dbus.glib import dbus.glib
#declare the connections to the daemon, so that they may be accessed # Declare the connections to the daemon, so that they may be accessed
#in any class # in any class.
bus = dbus.SystemBus() bus = dbus.SystemBus()
try: try:
print 'Attempting to connect daemon to gui...' print 'Attempting to connect daemon to GUI...'
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon') proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
print 'success' print 'Success'
except: except:
print 'daemon not running, running gksudo ./daemon.py...' print 'Daemon not running, trying to start it automatically.'
misc.PromptToStartDaemon() misc.PromptToStartDaemon()
time.sleep(1) time.sleep(1)
try: try:
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon') proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
print 'Daemon started succesfully'
except: except:
print 'daemon still not running, aborting.' print 'Daemon still not running, aborting.'
sys.exit(1)
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless') wireless = dbus.Interface(proxy_obj, 'org.wicd.daemon.wireless')
wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired') wired = dbus.Interface(proxy_obj, 'org.wicd.daemon.wired')
@@ -65,19 +70,19 @@ config = dbus.Interface(proxy_obj, 'org.wicd.daemon.config')
#http://www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/ #http://www.learningpython.com/2006/12/03/translating-your-pythonpygtk-application/
#which is also under GPLv2 #which is also under GPLv2
#Get the local directory since we are not installing anything # Get the local directory since we are not installing anything.
local_path = os.path.realpath(os.path.dirname(sys.argv[0])) + '/translations' local_path = os.path.realpath(os.path.dirname(sys.argv[0])) + '/translations'
# Init the list of languages to support # Init the list of languages to support.
langs = list() langs = list()
#Check the default locale # Check the default locale.
lc, encoding = locale.getdefaultlocale() lc, encoding = locale.getdefaultlocale()
if (lc): if (lc):
#If we have a default, it's the first in the list # If we have a default, it's the first in the list.
langs = [lc] langs = [lc]
# Now lets get all of the supported languages on the system # Now lets get all of the supported languages on the system
osLanguage = os.environ.get('LANGUAGE', None) osLanguage = os.environ.get('LANGUAGE', None)
if (osLanguage): if (osLanguage):
#langage comes back something like en_CA:en_US:en_GB:en # Language comes back something like en_CA:en_US:en_GB:en
#on linuxy systems, on Win32 it's nothing, so we need to #on linuxy systems, on Win32 it's nothing, so we need to
#split it up into a list #split it up into a list
langs += osLanguage.split(":") langs += osLanguage.split(":")
@@ -97,8 +102,8 @@ lang = gettext.translation('wicd', local_path, languages=langs, fallback = True)
#map _() to self.lang.gettext() which will translate them. #map _() to self.lang.gettext() which will translate them.
_ = lang.gettext _ = lang.gettext
#keep all the language strings in a dictionary # Keep all the language strings in a dictionary
#by the english words # by the english words.
# I'm not sure this is the best way to do it # I'm not sure this is the best way to do it
# but it works and makes it easy for me :) # but it works and makes it easy for me :)
########## ##########
@@ -190,7 +195,11 @@ language['setting_broadcast_address'] = _('Setting broadcast address...')
language['setting_static_dns'] = _('Setting static DNS servers...') language['setting_static_dns'] = _('Setting static DNS servers...')
language['setting_static_ip'] = _('Setting static IP addresses...') language['setting_static_ip'] = _('Setting static IP addresses...')
language['running_dhcp'] = _('Obtaining IP address...') language['running_dhcp'] = _('Obtaining IP address...')
language['no_dhcp_offers'] = _('Connection Failed: No DHCP offers received. \
Couldn\'t get an IP Address.')
language['dhcp_failed'] = _('Connection Failed: Unable to Get IP Address')
language['aborted'] = _('Connection cancelled') language['aborted'] = _('Connection cancelled')
language['bad_pass'] = _('Connection Failed: Bad password')
language['done'] = _('Done connecting...') language['done'] = _('Done connecting...')
######################################## ########################################
@@ -210,7 +219,7 @@ class LinkButton(gtk.EventBox):
self.show_all() self.show_all()
def __setHandCursor(self,widget): def __setHandCursor(self,widget):
#we need this to set the cursor to a hand for the link labels # We need this to set the cursor to a hand for the link labels.
#I'm not entirely sure what it does :P #I'm not entirely sure what it does :P
hand = gtk.gdk.Cursor(gtk.gdk.HAND1) hand = gtk.gdk.Cursor(gtk.gdk.HAND1)
widget.window.set_cursor(hand) widget.window.set_cursor(hand)
@@ -239,7 +248,7 @@ class LabelEntry(gtk.HBox):
self.show() self.show()
def set_text(self,text): def set_text(self,text):
#for compatibility... # For compatibility...
self.entry.set_text(text) self.entry.set_text(text)
def get_text(self): def get_text(self):
@@ -259,7 +268,7 @@ class LabelEntry(gtk.HBox):
self.label.set_sensitive(value) self.label.set_sensitive(value)
def hide_characters(self,widget=None,event=None): def hide_characters(self,widget=None,event=None):
#when the box looses focus, hide them # When the box looses focus, hide them
if self.auto_hide_text and widget: if self.auto_hide_text and widget:
self.entry.set_visibility(False) self.entry.set_visibility(False)
@@ -282,7 +291,7 @@ def noneToString(text):
return str(text) return str(text)
def noneToBlankString(text): def noneToBlankString(text):
'''if text is None, 'None', or '' then return '', otherwise return str(text)''' '''If text is None, 'None', or '' then return '', otherwise return str(text)'''
if text == None or text == "None" or text == "": if text == None or text == "None" or text == "":
return "" return ""
else: else:
@@ -296,7 +305,7 @@ def stringToNone(text):
return str(text) return str(text)
def stringToBoolean(text): def stringToBoolean(text):
'''turns a "True" to True or a "False" to False otherwise returns the text''' '''Turns a "True" to True or a "False" to False otherwise returns the text'''
if text == "True": if text == "True":
return True return True
if text == "False": if text == "False":
@@ -304,7 +313,7 @@ def stringToBoolean(text):
return text return text
def checkboxTextboxToggle(checkbox,textboxes): def checkboxTextboxToggle(checkbox,textboxes):
#really bad practice, but checkbox == self # Really bad practice, but checkbox == self
for textbox in textboxes: for textbox in textboxes:
textbox.set_sensitive(checkbox.get_active()) textbox.set_sensitive(checkbox.get_active())
@@ -314,7 +323,7 @@ def checkboxTextboxToggle(checkbox,textboxes):
class PrettyNetworkEntry(gtk.HBox): class PrettyNetworkEntry(gtk.HBox):
'''adds an image and a connect button to a NetworkEntry''' '''Adds an image and a connect button to a NetworkEntry'''
def __init__(self,expander): def __init__(self,expander):
gtk.HBox.__init__(self) gtk.HBox.__init__(self)
# Add the stuff to the hbox (self) # Add the stuff to the hbox (self)
@@ -333,10 +342,9 @@ class PrettyNetworkEntry(gtk.HBox):
class PrettyWiredNetworkEntry(PrettyNetworkEntry): class PrettyWiredNetworkEntry(PrettyNetworkEntry):
def __init__(self): def __init__(self):
PrettyNetworkEntry.__init__(self,WiredNetworkEntry()) PrettyNetworkEntry.__init__(self,WiredNetworkEntry())
#center the picture and pad it a bit # Center the picture and pad it a bit
self.image = gtk.Image() self.image = gtk.Image()
self.image.set_alignment(.5,0) self.image.set_alignment(.5,0)
self.image.set_size_request(60,-1) self.image.set_size_request(60,-1)
self.image.set_from_icon_name("network-wired",6) self.image.set_from_icon_name("network-wired",6)
self.image.show() self.image.show()
@@ -381,23 +389,24 @@ class PrettyWirelessNetworkEntry(PrettyNetworkEntry):
# "converted" to strength bars, so suggestions from people # "converted" to strength bars, so suggestions from people
# for a better way would be welcome. # for a better way would be welcome.
if dbm_strength >= -60: if dbm_strength >= -60:
self.image.set_from_file(wpath.images + 'signal-100.png') signal_img = 'signal-100.png'
elif dbm_strength >= -70: elif dbm_strength >= -70:
self.image.set_from_file(wpath.images + 'signal-75.png') signal_img = 'signal-75.png'
elif dbm_strength >= -80: elif dbm_strength >= -80:
self.image.set_from_file(wpath.images + 'signal-50.png') signal_img = 'signal-50.png'
else: else:
self.image.set_from_file(wpath.images + 'signal-25.png') signal_img = 'signal-25.png'
else: else:
# Uses normal link quality, should be fine in most cases # Uses normal link quality, should be fine in most cases
if strength > 75: if strength > 75:
self.image.set_from_file(wpath.images + 'signal-100.png') signal_img = 'signal-100.png'
elif strength > 50: elif strength > 50:
self.image.set_from_file(wpath.images + 'signal-75.png') signal_img = 'signal-75.png'
elif strength > 25: elif strength > 25:
self.image.set_from_file(wpath.images + 'signal-50.png') signal_img = 'signal-50.png'
else: else:
self.image.set_from_file(wpath.images + 'signal-25.png') signal_img = 'signal-25.png'
self.image.set_from_file(wpath.images + signal_img)
self.expander.setSignalStrength(strength, dbm_strength) self.expander.setSignalStrength(strength, dbm_strength)
def setMACAddress(self,address): def setMACAddress(self,address):
@@ -412,10 +421,11 @@ class PrettyWirelessNetworkEntry(PrettyNetworkEntry):
def setMode(self,mode): def setMode(self,mode):
self.expander.setMode(mode) self.expander.setMode(mode)
class NetworkEntry(gtk.Expander): class NetworkEntry(gtk.Expander):
'''the basis for the entries in the network list''' '''The basis for the entries in the network list'''
def __init__(self): def __init__(self):
#make stuff exist, this is pretty long and boring # Make stuff exist, this is pretty long and boring.
gtk.Expander.__init__(self) gtk.Expander.__init__(self)
self.txtIP = LabelEntry(language['ip']) self.txtIP = LabelEntry(language['ip'])
self.txtIP.entry.connect('focus-out-event',self.setDefaults) self.txtIP.entry.connect('focus-out-event',self.setDefaults)
@@ -449,27 +459,27 @@ class NetworkEntry(gtk.Expander):
self.checkboxStaticDNS.connect("toggled",self.toggleDNSCheckbox) self.checkboxStaticDNS.connect("toggled",self.toggleDNSCheckbox)
self.checkboxGlobalDNS.connect("toggled",self.toggleGlobalDNSCheckbox) self.checkboxGlobalDNS.connect("toggled",self.toggleGlobalDNSCheckbox)
self.add(self.vboxTop) self.add(self.vboxTop)
#start with all disabled, then they will be enabled later # Start with all disabled, then they will be enabled later.
self.checkboxStaticIP.set_active(False) self.checkboxStaticIP.set_active(False)
self.checkboxStaticDNS.set_active(False) self.checkboxStaticDNS.set_active(False)
def setDefaults(self,widget=None,event=None): def setDefaults(self,widget=None,event=None):
#after the user types in the IP address, # After the user types in the IP address,
#help them out a little # help them out a little.
ipAddress = self.txtIP.get_text() #for easy typing :) ipAddress = self.txtIP.get_text() # For easy typing :)
netmask = self.txtNetmask netmask = self.txtNetmask
gateway = self.txtGateway gateway = self.txtGateway
ip_parts = misc.IsValidIP(ipAddress) ip_parts = misc.IsValidIP(ipAddress)
if ip_parts: if ip_parts:
if stringToNone(gateway.get_text()) == None: #make sure the gateway box is blank if stringToNone(gateway.get_text()) == None: # Make sure the gateway box is blank
#fill it in with a .1 at the end # Fill it in with a .1 at the end
gateway.set_text('.'.join(ip_parts[0:3]) + '.1') gateway.set_text('.'.join(ip_parts[0:3]) + '.1')
if stringToNone(netmask.get_text()) == None: # Make sure the netmask is blank if stringToNone(netmask.get_text()) == None: # Make sure the netmask is blank
netmask.set_text('255.255.255.0') # Fill in the most common one netmask.set_text('255.255.255.0') # Fill in the most common one
def resetStaticCheckboxes(self): def resetStaticCheckboxes(self):
#enable the right stuff # Enable the right stuff
if not stringToNone(self.txtIP.get_text()) == None: if not stringToNone(self.txtIP.get_text()) == None:
self.checkboxStaticIP.set_active(True) self.checkboxStaticIP.set_active(True)
self.checkboxStaticDNS.set_active(True) self.checkboxStaticDNS.set_active(True)
@@ -492,10 +502,9 @@ class NetworkEntry(gtk.Expander):
self.toggleGlobalDNSCheckbox() self.toggleGlobalDNSCheckbox()
def toggleIPCheckbox(self,widget=None): def toggleIPCheckbox(self,widget=None):
#should disable the static IP text boxes # Should disable the static IP text boxes,
# and also enable the DNS checkbox when # and also enable the DNS checkbox when
#disabled and disable when enabled # disabled and disable when enabled.
if self.checkboxStaticIP.get_active(): if self.checkboxStaticIP.get_active():
self.checkboxStaticDNS.set_active(True) self.checkboxStaticDNS.set_active(True)
self.checkboxStaticDNS.set_sensitive(False) self.checkboxStaticDNS.set_sensitive(False)
@@ -532,7 +541,7 @@ class NetworkEntry(gtk.Expander):
self.txtDNS3.set_sensitive(not self.checkboxGlobalDNS.get_active()) self.txtDNS3.set_sensitive(not self.checkboxGlobalDNS.get_active())
class WiredNetworkEntry(NetworkEntry): class WiredNetworkEntry(NetworkEntry):
#creates the wired network expander # Creates the wired network expander.
def __init__(self): def __init__(self):
NetworkEntry.__init__(self) NetworkEntry.__init__(self)
self.set_label(language['wired_network']) self.set_label(language['wired_network'])
@@ -541,8 +550,8 @@ class WiredNetworkEntry(NetworkEntry):
self.isFullGUI = True self.isFullGUI = True
self.profileList = config.GetWiredProfileList() self.profileList = config.GetWiredProfileList()
if self.profileList: #make sure there is something in it... if self.profileList: # Make sure there is something in it...
for x in config.GetWiredProfileList(): #add all the names to the combobox for x in config.GetWiredProfileList(): # Add all the names to the combobox
self.comboProfileNames.append_text(x) self.comboProfileNames.append_text(x)
self.hboxTemp = gtk.HBox(False,0) self.hboxTemp = gtk.HBox(False,0)
hboxDef = gtk.HBox(False,0) hboxDef = gtk.HBox(False,0)
@@ -668,19 +677,19 @@ class WiredNetworkEntry(NetworkEntry):
self.resetStaticCheckboxes() self.resetStaticCheckboxes()
class WirelessNetworkEntry(NetworkEntry): class WirelessNetworkEntry(NetworkEntry):
#this class is respsponsible for creating the expander # This class is respsponsible for creating the expander
#in each wirelessnetwork entry # in each wirelessnetwork entry.
def __init__(self,networkID): def __init__(self,networkID):
self.networkID = networkID self.networkID = networkID
#create the data labels # Create the data labels
NetworkEntry.__init__(self) NetworkEntry.__init__(self)
print "ESSID : " + wireless.GetWirelessProperty(networkID,"essid") print "ESSID : " + wireless.GetWirelessProperty(networkID,"essid")
self.set_label(wireless.GetWirelessProperty(networkID,"essid")) self.set_label(wireless.GetWirelessProperty(networkID,"essid"))
self.essid = wireless.GetWirelessProperty(networkID,"essid") self.essid = wireless.GetWirelessProperty(networkID,"essid")
#make the vbox to hold the encryption stuff # Make the vbox to hold the encryption stuff.
self.vboxEncryptionInformation = gtk.VBox(False,0) self.vboxEncryptionInformation = gtk.VBox(False,0)
#make the combo box # Make the combo box.
self.comboEncryption = gtk.combo_box_new_text() self.comboEncryption = gtk.combo_box_new_text()
self.checkboxEncryption = gtk.CheckButton(language['use_encryption']) self.checkboxEncryption = gtk.CheckButton(language['use_encryption'])
self.lblStrength = GreyLabel() self.lblStrength = GreyLabel()
@@ -888,7 +897,7 @@ class appGui:
dic = { "refresh_clicked" : self.refresh_networks, dic = { "refresh_clicked" : self.refresh_networks,
"quit_clicked" : self.exit, "quit_clicked" : self.exit,
"disconnect_clicked" : self.disconnect_wireless, "disconnect_clicked" : self.disconnect,
"main_exit" : self.exit, "main_exit" : self.exit,
"cancel_clicked" : self.cancel_connect, "cancel_clicked" : self.cancel_connect,
"connect_clicked" : self.connect_hidden, "connect_clicked" : self.connect_hidden,
@@ -981,8 +990,8 @@ class appGui:
def toggleEncryptionCheck(self,widget=None): def toggleEncryptionCheck(self,widget=None):
self.keyEntry.set_sensitive(self.useEncryptionCheckbox.get_active()) self.keyEntry.set_sensitive(self.useEncryptionCheckbox.get_active())
def disconnect_wireless(self,widget=None): def disconnect(self,widget=None):
wireless.DisconnectWireless() daemon.Disconnect()
def about_dialog(self,widget,event=None): def about_dialog(self,widget,event=None):
dialog = gtk.AboutDialog() dialog = gtk.AboutDialog()
@@ -1289,7 +1298,7 @@ class appGui:
# if it exists. maybe kept as a value in the network entry? Not sure... # if it exists. maybe kept as a value in the network entry? Not sure...
print "connecting to wireless network..." print "connecting to wireless network..."
config.SaveWirelessNetworkProfile(networkid) config.SaveWirelessNetworkProfile(networkid)
wireless.ConnectWireless(networkid) wireless.ConnectWireless(networkid, True)
if type == "wired": if type == "wired":
print "wired" print "wired"
@@ -1314,7 +1323,7 @@ class appGui:
wired.SetWiredProperty("dns3",'') wired.SetWiredProperty("dns3",'')
config.SaveWiredNetworkProfile(networkentry.expander.comboProfileNames.get_active_text()) config.SaveWiredNetworkProfile(networkentry.expander.comboProfileNames.get_active_text())
wired.ConnectWired() wired.ConnectWired(True)
def exit(self, widget=None, event=None): def exit(self, widget=None, event=None):
self.window.hide() self.window.hide()
@@ -1327,9 +1336,6 @@ class appGui:
def show_win(self): def show_win(self):
self.window.show() self.window.show()
# hide the status bar, as it might be confusing if it
# pops up randomly :)
self.status_area.hide_all()
self.is_visible = True self.is_visible = True
if __name__ == '__main__': if __name__ == '__main__':

4
launchdaemon.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
echo "Starting wicd daemon..."
/opt/wicd/daemon.py 2> /dev/null

94
misc.py
View File

@@ -1,14 +1,20 @@
''' Misc - miscellaneous functions for wicd ''' ''' Misc - miscellaneous functions for wicd '''
# Pretty much useless to anyone else...
# But if it is useful, feel free to use under the terms of the GPL
#
# This is released under the
# GNU General Public License
# The terms can be found at
# http://www.gnu.org/copyleft/gpl.html
# #
# Copyright (C) 2007 Adam Blackburn # Copyright (C) 2007 Adam Blackburn
# Copyright (C) 2007 Dan O'Reilly
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License Version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import os import os
@@ -17,18 +23,42 @@ import locale
import gettext import gettext
import time import time
import sys import sys
from subprocess import *
if __name__ == '__main__': if __name__ == '__main__':
wpath.chdir(__file__) wpath.chdir(__file__)
def Run(cmd, include_std_error = False): def Run(cmd, include_stderr=False, return_pipe=False):
''' Run a command ''' ''' Run a command
if not include_std_error:
f = os.popen( cmd , "r") Runs the given command, returning either the output
return f.read() of the program, or a pipe to read output from.
keyword arguments --
cmd - The command to execute
include_std_err - Boolean specifying if stderr should
be included in the pipe to the cmd.
return_pipe - Boolean specifying if a pipe to the
command should be returned. If it is
false, all that will be returned is
one output string from the command.
'''
cmd = to_unicode(str(cmd))
if include_stderr:
err = STDOUT
fds = True
else: else:
input, out_err = os.popen4( cmd, 'r') err = None
return out_err.read() fds = False
f = Popen(cmd, shell=True, stdout=PIPE, stderr=err, close_fds=fds)
if return_pipe:
return f.stdout
else:
return f.communicate()[0]
def IsValidIP(ip): def IsValidIP(ip):
''' Make sure an entered IP is valid ''' ''' Make sure an entered IP is valid '''
@@ -41,10 +71,11 @@ def IsValidIP(ip):
def PromptToStartDaemon(): def PromptToStartDaemon():
''' Prompt the user to start the daemon ''' ''' Prompt the user to start the daemon '''
# script execution doesn't work correctly if daemon gets autostarted, daemonloc = wpath.bin + 'launchdaemon.sh'
# so just prompt user to start manually gksudo_args = ['gksudo', '--message',
print 'You need to start the daemon before using the gui or tray. Use \ 'Wicd needs to access your computer\'s network cards.',
the command \'sudo /etc/init.d/wicd start\'.' '--', daemonloc]
os.spawnvpe(os.P_WAIT, 'gksudo', gksudo_args, os.environ)
def RunRegex(regex, string): def RunRegex(regex, string):
''' runs a regex search on a string ''' ''' runs a regex search on a string '''
@@ -63,24 +94,8 @@ def WriteLine(my_file, text):
my_file.write(text + "\n") my_file.write(text + "\n")
def ExecuteScript(script): def ExecuteScript(script):
''' Execute a command ''' Execute a command '''
os.system(script + ' &')
Executes a given command by forking a new process and
calling run-script.py
'''
pid = os.fork()
if not pid:
os.setsid()
os.umask(0)
pid = os.fork()
if not pid:
print Run('./run-script.py ' + script)
os._exit(0)
os._exit(0)
os.wait()
def ReadFile(filename): def ReadFile(filename):
''' read in a file and return it's contents as a string ''' ''' read in a file and return it's contents as a string '''
@@ -227,6 +242,13 @@ def to_unicode(x):
else: else:
return x.decode('utf-8').encode('utf-8') return x.decode('utf-8').encode('utf-8')
def error(parent, message):
""" Shows an error dialog """
dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR,
gtk.BUTTONS_OK)
dialog.set_markup(message)
dialog.run()
dialog.destroy()
class LogWriter(): class LogWriter():

View File

@@ -48,6 +48,7 @@ import misc
import wnettools import wnettools
import wpath import wpath
import os import os
import time
if __name__ == '__main__': if __name__ == '__main__':
wpath.chdir(__file__) wpath.chdir(__file__)
@@ -104,6 +105,8 @@ class ConnectThread(threading.Thread):
self.wireless_interface = wireless self.wireless_interface = wireless
self.wired_interface = wired self.wired_interface = wired
self.is_connecting = False self.is_connecting = False
self.is_aborted = False
self.abort_msg = None
self.before_script = before_script self.before_script = before_script
self.after_script = after_script self.after_script = after_script
self.disconnect_script = disconnect_script self.disconnect_script = disconnect_script
@@ -123,7 +126,9 @@ class ConnectThread(threading.Thread):
""" """
self.lock.acquire() self.lock.acquire()
try:
self.connecting_message = status self.connecting_message = status
finally:
self.lock.release() self.lock.release()
@@ -135,7 +140,9 @@ class ConnectThread(threading.Thread):
""" """
self.lock.acquire() self.lock.acquire()
try:
message = self.connecting_message message = self.connecting_message
finally:
self.lock.release() self.lock.release()
return message return message
@@ -147,11 +154,12 @@ class ConnectThread(threading.Thread):
""" """
self.SetStatus(reason) self.SetStatus(reason)
self.is_aborted = True
self.abort_msg = reason
self.is_connecting = False self.is_connecting = False
print 'exiting connection thread' print 'exiting connection thread'
class Wireless(Controller): class Wireless(Controller):
""" A wrapper for common wireless interface functions. """ """ A wrapper for common wireless interface functions. """
@@ -394,7 +402,7 @@ class WirelessConnectThread(ConnectThread):
return return
# Execute pre-connection script if necessary # Execute pre-connection script if necessary
if self.before_script != '' and self.before_script != None: if self.before_script != '' and self.before_script is not None:
print 'Executing pre-connection script' print 'Executing pre-connection script'
misc.ExecuteScript(self.before_script) misc.ExecuteScript(self.before_script)
@@ -427,7 +435,7 @@ class WirelessConnectThread(ConnectThread):
# Check to see if we need to generate a PSK (only for non-ralink # Check to see if we need to generate a PSK (only for non-ralink
# cards). # cards).
if self.wpa_driver != 'ralink legacy': if self.wpa_driver != 'ralink legacy':
if not self.network.get('key') == None: if not self.network.get('key') is None:
self.SetStatus('generating_psk') self.SetStatus('generating_psk')
print 'Generating psk...' print 'Generating psk...'
@@ -437,10 +445,11 @@ class WirelessConnectThread(ConnectThread):
misc.Run('wpa_passphrase "' + self.network['essid'] + misc.Run('wpa_passphrase "' + self.network['essid'] +
'" "' + self.network['key'] + '"')) '" "' + self.network['key'] + '"'))
# Generate the wpa_supplicant file... # Generate the wpa_supplicant file...
if not self.network.get('enctype') == None: if self.network.get('enctype') is not None:
self.SetStatus('generating_wpa_config') self.SetStatus('generating_wpa_config')
print 'Attempting to authenticate...' print 'Attempting to authenticate...'
wiface.Authenticate(self.network) wiface.Authenticate(self.network)
auth_time = time.time()
if self.should_die: if self.should_die:
wiface.Up() wiface.Up()
@@ -464,16 +473,30 @@ class WirelessConnectThread(ConnectThread):
self.connect_aborted('aborted') self.connect_aborted('aborted')
return return
if self.network.get('enctype') is not None:
# Allow some time for wpa_supplicant to associate.
# Hopefully 3 sec is enough. If it proves to be inconsistent,
# we might have to try to monitor wpa_supplicant more closely,
# so we can tell exactly when it fails/succeeds.
elapsed = time.time() - auth_time
if elapsed < 3 and elapsed >= 0:
time.sleep(3 - elapsed)
# Make sure wpa_supplicant was able to associate.
if not wiface.ValidateAuthentication():
self.connect_aborted('bad_pass')
return
wiface.SetMode(self.network['mode']) wiface.SetMode(self.network['mode'])
wiface.Associate(self.network['essid'], wiface.Associate(self.network['essid'], self.network['channel'],
self.network['channel'], self.network['bssid']) self.network['bssid'])
# Authenticate after association for Ralink legacy cards. # Authenticate after association for Ralink legacy cards.
if self.wpa_driver == 'ralink legacy': if self.wpa_driver == 'ralink legacy':
if self.network.get('key') != None: if self.network.get('key') is not None:
wiface.Authenticate(self.network) wiface.Authenticate(self.network)
if not self.network.get('broadcast') == None: if self.network.get('broadcast') is not None:
self.SetStatus('setting_broadcast_address') self.SetStatus('setting_broadcast_address')
print 'Setting the broadcast address...' + self.network['broadcast'] print 'Setting the broadcast address...' + self.network['broadcast']
@@ -483,18 +506,20 @@ class WirelessConnectThread(ConnectThread):
self.connect_aborted('aborted') self.connect_aborted('aborted')
return return
if not self.network.get('ip') == None: if self.network.get('ip') is not None:
self.SetStatus('setting_static_ip') self.SetStatus('setting_static_ip')
print 'Setting static IP : ' + self.network['ip'] print 'Setting static IP : ' + self.network['ip']
wiface.SetAddress(self.network['ip'], self.network['netmask']) wiface.SetAddress(self.network['ip'], self.network['netmask'])
print 'Setting default gateway : ' + self.network['gateway'] print 'Setting default gateway : ' + self.network['gateway']
wiface.SetDefaultRoute(self.network['gateway']) wiface.SetDefaultRoute(self.network['gateway'])
else: else:
# Run dhcp... # Run DHCP...
self.SetStatus('running_dhcp') self.SetStatus('running_dhcp')
print "Running DHCP" print "Running DHCP"
if not self.should_die: dhcp_status = wiface.StartDHCP()
wiface.StartDHCP() if dhcp_status in ['no_dhcp_offers', 'dhcp_failed']:
self.connect_aborted(dhcp_status)
return
if ((self.network.get('dns1') or self.network.get('dns2') or if ((self.network.get('dns1') or self.network.get('dns2') or
self.network.get('dns3')) and self.network.get('use_static_dns')): self.network.get('dns3')) and self.network.get('use_static_dns')):
@@ -697,8 +722,10 @@ class WiredConnectThread(ConnectThread):
# Run dhcp... # Run dhcp...
self.SetStatus('running_dhcp') self.SetStatus('running_dhcp')
print "Running DHCP" print "Running DHCP"
if not self.should_die: dhcp_status = liface.StartDHCP()
liface.StartDHCP() if dhcp_status in ['no_dhcp_offers', 'dhcp_failed']:
self.connect_aborted(dhcp_status)
return
if ((self.network.get('dns1') or self.network.get('dns2') or if ((self.network.get('dns1') or self.network.get('dns2') or
self.network.get('dns3')) and self.network.get('use_static_dns')): self.network.get('dns3')) and self.network.get('use_static_dns')):

27
wicd.py
View File

@@ -42,6 +42,7 @@ import gobject
import dbus import dbus
import dbus.service import dbus.service
import getopt import getopt
import time
# Import egg.trayicon if we're using an older gtk version # Import egg.trayicon if we're using an older gtk version
if not (gtk.gtk_version[0] >= 2 and gtk.gtk_version[1] >= 10): if not (gtk.gtk_version[0] >= 2 and gtk.gtk_version[1] >= 10):
@@ -80,8 +81,15 @@ try:
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon') proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
print 'Success.' print 'Success.'
except Exception: except Exception:
print 'Daemon not running...' print 'Can\'t connect to the daemon, trying to start it automatically...'
misc.PromptToStartDaemon() misc.PromptToStartDaemon()
time.sleep(1)
try:
print 'Attempting to connect tray to daemon...'
proxy_obj = bus.get_object('org.wicd.daemon', '/org/wicd/daemon')
print 'Success.'
except:
print 'Failed to start daemon. Aborting.'
sys.exit(1) sys.exit(1)
daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon') daemon = dbus.Interface(proxy_obj, 'org.wicd.daemon')
@@ -108,12 +116,12 @@ class TrayIcon():
self.tr = self.EggTrayIconGUI(use_tray) self.tr = self.EggTrayIconGUI(use_tray)
else: else:
self.tr = self.StatusTrayIconGUI(use_tray) self.tr = self.StatusTrayIconGUI(use_tray)
self.icon_info = self.TrayConnectionInfo(self.tr) self.icon_info = self.TrayConnectionInfo(self.tr, use_tray)
class TrayConnectionInfo(): class TrayConnectionInfo():
"""Class for updating the tray icon status""" """Class for updating the tray icon status"""
def __init__(self, tr): def __init__(self, tr, use_tray=True):
"""Initialize variables needed for the icon status methods.""" """Initialize variables needed for the icon status methods."""
self.last_strength = -2 self.last_strength = -2
self.still_wired = False self.still_wired = False
@@ -121,6 +129,7 @@ class TrayIcon():
self.tried_reconnect = False self.tried_reconnect = False
self.connection_lost_counter = 0 self.connection_lost_counter = 0
self.tr = tr self.tr = tr
self.use_tray = use_tray
self.update_tray_icon() self.update_tray_icon()
def wired_profile_chooser(self): def wired_profile_chooser(self):
@@ -130,6 +139,7 @@ class TrayIcon():
def update_tray_icon(self): def update_tray_icon(self):
"""Updates the tray icon and current connection status""" """Updates the tray icon and current connection status"""
if self.use_tray == False: return False
# If we're currently connecting, we can shortcut all other checks # If we're currently connecting, we can shortcut all other checks
if daemon.CheckIfConnecting(): if daemon.CheckIfConnecting():
@@ -205,7 +215,9 @@ class TrayIcon():
class TrayIconGUI(): class TrayIconGUI():
"""Base Tray Icon class """Base Tray Icon class
Implements methods and variables used by both egg/StatusIcon tray icons. Implements methods and variables used by both egg/StatusIcon
tray icons.
""" """
def __init__(self, use_tray): def __init__(self, use_tray):
menu = """ menu = """
@@ -396,20 +408,18 @@ def main(argv):
if opt in ('-h', '--help'): if opt in ('-h', '--help'):
usage() usage()
sys.exit() sys.exit()
if opt in ('-n', '--no-tray'): elif opt in ('-n', '--no-tray'):
use_tray = False use_tray = False
# Redirect stderr and stdout for logging purposes # Redirect stderr and stdout for logging purposes
#sys.stderr = log #sys.stderr = log
#sys.stdout = log #sys.stdout = log
print 'Done initalizing, starting...'
# Set up the tray icon GUI and backend # Set up the tray icon GUI and backend
tray_icon = TrayIcon(use_tray) tray_icon = TrayIcon(use_tray)
# Check to see if wired profile chooser was called before icon # Check to see if wired profile chooser was called before icon
# was launched (typically happens on startup or daemon restart) # was launched (typically happens on startup or daemon restart).
if daemon.GetNeedWiredProfileChooser(): if daemon.GetNeedWiredProfileChooser():
daemon.SetNeedWiredProfileChooser(False) daemon.SetNeedWiredProfileChooser(False)
tray_icon.icon_info.wired_profile_chooser() tray_icon.icon_info.wired_profile_chooser()
@@ -419,6 +429,7 @@ def main(argv):
bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon, bus.add_signal_receiver(tray_icon.icon_info.update_tray_icon,
'StatusChanged', 'org.wicd.daemon') 'StatusChanged', 'org.wicd.daemon')
print 'Done.'
mainloop = gobject.MainLoop() mainloop = gobject.MainLoop()
mainloop.run() mainloop.run()

View File

@@ -33,6 +33,7 @@ class WirelessInterface() -- Control a wireless network interface.
import misc import misc
import re import re
import wpath import wpath
import time
# Compile the regex patterns that will be used to search the output of iwlist # Compile the regex patterns that will be used to search the output of iwlist
# scan for info these are well tested, should work on most cards # scan for info these are well tested, should work on most cards
@@ -54,6 +55,11 @@ altwpa_pattern = re.compile('(wpa_ie)', re.I | re.M | re.S)
wpa1_pattern = re.compile('(WPA Version 1)', re.I | re.M | re.S) wpa1_pattern = re.compile('(WPA Version 1)', re.I | re.M | re.S)
wpa2_pattern = re.compile('(WPA2)', re.I | re.M | re.S) wpa2_pattern = re.compile('(WPA2)', re.I | re.M | re.S)
# Patterns for wpa_cli output
auth_pattern = re.compile('.*wpa_state=(.*?)\n', re.I | re.M | re.S)
RALINK_DRIVER = 'ralink legacy'
def SetDNS(dns1=None, dns2=None, dns3=None): def SetDNS(dns1=None, dns2=None, dns3=None):
""" Set the DNS of the system to the specified DNS servers. """ Set the DNS of the system to the specified DNS servers.
@@ -140,12 +146,53 @@ class Interface(object):
if self.verbose: print cmd if self.verbose: print cmd
misc.Run(cmd) misc.Run(cmd)
def _parse_dhclient(self, pipe):
""" Parse the output of dhclient
Parses the output of dhclient and returns the status of
the connection attempt.
"""
dhclient_complete = False
dhclient_success = False
dh_no_offers = False
while not dhclient_complete:
line = pipe.readline()
if line == '': # Empty string means dhclient is done.
dhclient_complete = True
else:
print line.strip('\n')
if line.startswith('bound'):
dhclient_success = True
dhclient_complete = True
if line.startswith('No DHCPOFFERS'):
# We don't break in this case because dhclient will
# try to use an old lease if possible, so we may
# still make a successful connection.
dh_no_offers = True
if dhclient_success:
print 'DHCP connection successful'
return 'success'
if dh_no_offers:
print 'DHCP connection failed: No DHCP offers recieved'
return 'no_dhcp_offers'
else:
print 'DHCP connection failed: Reason unknown'
return 'dhcp_failed'
def StartDHCP(self): def StartDHCP(self):
""" Start the DHCP client to obtain an IP address. """ """ Start the DHCP client to obtain an IP address. """
# TODO: Not all distros use dhclient to get an IP. We should
# add a way to determine what method is used (or let the user tell
# us), and run the cmd based on that.
cmd = 'dhclient ' + self.iface cmd = 'dhclient ' + self.iface
if self.verbose: print cmd if self.verbose: print cmd
misc.Run(cmd) pipe = misc.Run(cmd, include_stderr=True, return_pipe=True)
return self._parse_dhclient(pipe)
def StopDHCP(self): def StopDHCP(self):
@@ -202,19 +249,34 @@ class WiredInterface(Interface):
def GetPluggedIn(self): def GetPluggedIn(self):
""" Get the current physical connection state. """ """ Get the current physical connection state.
mii_tool_data = misc.Run( 'mii-tool ' + self.iface,True)
if not misc.RunRegex(re.compile('(Invalid argument)',re.DOTALL | re.I | re.M | re.S),mii_tool_data) == None: The method will first attempt to use ethtool do determine
physical connection state. Should ethtool fail to run properly,
mii-tool will be used instead.
"""
link_tool = 'ethtool'
tool_data = misc.Run(link_tool + ' ' + self.iface, True)
if misc.RunRegex(re.compile('(Operation not supported)|\
(ethtool: command not found)', re.I),
tool_data) is not None:
print "ethtool check failed, falling back to mii-tool"
link_tool = 'mii-tool'
if misc.RunRegex(re.compile('(Invalid argument)', re.I | re.M | re.S),
tool_data) is not None:
print 'wired interface appears down, putting up for mii-tool check' print 'wired interface appears down, putting up for mii-tool check'
misc.Run( 'ifconfig ' + self.iface + ' up' ) self.Up()
mii_tool_data = misc.Run( 'mii-tool ' + self.iface)
if not misc.RunRegex(re.compile('(link ok)',re.DOTALL | re.I | re.M | re.S),mii_tool_data) == None: tool_data = misc.Run(link_tool + ' ' + self.iface)
if misc.RunRegex(re.compile('(Link detected: yes)|(link ok)',
re.I | re.M | re.S), tool_data) is not None:
return True return True
else: else:
return False return False
class WirelessInterface(Interface): class WirelessInterface(Interface):
""" Control a wireless network interface. """ """ Control a wireless network interface. """
def __init__(self, iface, verbose=False, wpa_driver='wext'): def __init__(self, iface, verbose=False, wpa_driver='wext'):
@@ -267,7 +329,7 @@ class WirelessInterface(Interface):
# Get available network info from iwpriv get_site_survey # Get available network info from iwpriv get_site_survey
# if we're using a ralink card (needed to get encryption info) # if we're using a ralink card (needed to get encryption info)
if self.wpa_driver == 'ralink legacy': if self.wpa_driver == RALINK_DRIVER:
ralink_info = self._GetRalinkScanInfo() ralink_info = self._GetRalinkScanInfo()
else: else:
ralink_info = None ralink_info = None
@@ -372,7 +434,7 @@ class WirelessInterface(Interface):
ap['mode'] = misc.RunRegex(mode_pattern, cell) ap['mode'] = misc.RunRegex(mode_pattern, cell)
# Break off here if we're using a ralink card # Break off here if we're using a ralink card
if self.wpa_driver == 'ralink legacy': if self.wpa_driver == RALINK_DRIVER:
ap = self._ParseRalinkAccessPoint(ap, ralink_info, cell) ap = self._ParseRalinkAccessPoint(ap, ralink_info, cell)
elif misc.RunRegex(wep_pattern, cell) == 'on': elif misc.RunRegex(wep_pattern, cell) == 'on':
# Encryption - Default to WEP # Encryption - Default to WEP
@@ -410,7 +472,7 @@ class WirelessInterface(Interface):
# quality displayed or it isn't found) # quality displayed or it isn't found)
if misc.RunRegex(signaldbm_pattern, cell): if misc.RunRegex(signaldbm_pattern, cell):
ap['strength'] = misc.RunRegex(signaldbm_pattern, cell) ap['strength'] = misc.RunRegex(signaldbm_pattern, cell)
elif self.wpa_driver != 'ralink legacy': # This is already set for ralink elif self.wpa_driver != RALINK_DRIVER: # This is already set for ralink
ap['strength'] = -1 ap['strength'] = -1
return ap return ap
@@ -521,7 +583,7 @@ class WirelessInterface(Interface):
""" """
misc.ParseEncryption(network) misc.ParseEncryption(network)
if self.wpa_driver == 'ralink legacy': if self.wpa_driver == RALINK_DRIVER:
self._AuthenticateRalinkLegacy(network) self._AuthenticateRalinkLegacy(network)
else: else:
cmd = ('wpa_supplicant -B -i ' + self.iface + ' -c "' cmd = ('wpa_supplicant -B -i ' + self.iface + ' -c "'
@@ -530,6 +592,52 @@ class WirelessInterface(Interface):
if self.verbose: print cmd if self.verbose: print cmd
misc.Run(cmd) misc.Run(cmd)
def ValidateAuthentication(self):
""" Validate WPA authentication.
Validate that the wpa_supplicant authentication
process was successful.
NOTE: It's possible this could return False,
even though in actuality wpa_supplicant just isn't
finished yet.
"""
# Right now there's no way to do this for these drivers
if self.wpa_driver == RALINK_DRIVER:
return True
cmd = 'wpa_cli -i ' + self.iface + ' status'
if self.verbose: print cmd
output = misc.Run(cmd)
result = misc.RunRegex(auth_pattern, output)
if result == "COMPLETED":
return True
elif result =="DISCONNECTED":
# Force a rescan to get wpa_supplicant moving again.
self._ForceSupplicantScan()
return self.ValidateAuthentication()
else:
print 'wpa_supplicant authentication may have failed.'
return False
pass
def _ForceSupplicantScan(self):
""" Force wpa_supplicant to rescan available networks.
This function forces wpa_supplicant to rescan, then sleeps
to allow the scan to finish and reassociation to take place.
This works around authentication validation failing for
wpa_supplicant sometimes becaues it remains in a DISCONNECTED
state for quite a while, before a rescan takes places, all before
even attempting to authenticate.
"""
print 'wpa_supplicant rescan forced...'
cmd = 'wpa_cli -i' + self.iface + ' scan'
misc.Run(cmd)
time.sleep(5)
print 'Trying to validate authentication again'
def _AuthenticateRalinkLegacy(self, network): def _AuthenticateRalinkLegacy(self, network):
""" Authenticate with the specified wireless network. """ Authenticate with the specified wireless network.