mirror of
https://github.com/gryf/wicd.git
synced 2025-12-20 21:08:06 +01:00
Merge.
This commit is contained in:
20
.bzrignore
20
.bzrignore
@@ -3,3 +3,23 @@ install.log
|
|||||||
uninstall.log
|
uninstall.log
|
||||||
.bzrignore
|
.bzrignore
|
||||||
vcsinfo.py
|
vcsinfo.py
|
||||||
|
build
|
||||||
|
build/*
|
||||||
|
init/*/*
|
||||||
|
wpath.py*
|
||||||
|
man/wicd-curses.8
|
||||||
|
man/wicd-manager-settings.conf.5
|
||||||
|
man/wicd-wired-settings.conf.5
|
||||||
|
man/wicd-wireless-settings.conf.5
|
||||||
|
man/wicd.8
|
||||||
|
other/50-wicd-suspend.sh
|
||||||
|
other/55wicd
|
||||||
|
other/80-wicd-connect.sh
|
||||||
|
other/WHEREAREMYFILES
|
||||||
|
other/wicd.conf
|
||||||
|
other/postinst
|
||||||
|
scripts/wicd
|
||||||
|
scripts/wicd-client
|
||||||
|
scripts/wicd-curses
|
||||||
|
translations/*
|
||||||
|
wicd/wpath.py
|
||||||
|
|||||||
3
AUTHORS
3
AUTHORS
@@ -1,2 +1,3 @@
|
|||||||
Adam Blackburn (compwiz18@users.sourceforge.net)
|
Adam Blackburn (compwiz18@gmail.com)
|
||||||
Dan O'Reilly (oreilldf@gmail.com)
|
Dan O'Reilly (oreilldf@gmail.com)
|
||||||
|
Andrew Psaltis (ampsaltis@gmail.com) (wicd-curses)
|
||||||
|
|||||||
@@ -110,13 +110,13 @@ class MaskingEdit(urwid.Edit):
|
|||||||
"""
|
"""
|
||||||
mask_mode = one of:
|
mask_mode = one of:
|
||||||
"always" : everything is a '*' all of the time
|
"always" : everything is a '*' all of the time
|
||||||
"on_focus" : everything is a '*' only when not in focus
|
"no_focus" : everything is a '*' only when not in focus
|
||||||
"off" : everything is always unmasked
|
"off" : everything is always unmasked
|
||||||
mask_char = the single character that masks all other characters in the field
|
mask_char = the single character that masks all other characters in the field
|
||||||
"""
|
"""
|
||||||
def __init__(self, caption = "", edit_text = "", multiline = False,
|
def __init__(self, caption = "", edit_text = "", multiline = False,
|
||||||
align = 'left', wrap = 'space', allow_tab = False,
|
align = 'left', wrap = 'space', allow_tab = False,
|
||||||
edit_pos = None, layout=None, mask_mode="masked",mask_char='*'):
|
edit_pos = None, layout=None, mask_mode="always",mask_char='*'):
|
||||||
self.mask_mode = mask_mode
|
self.mask_mode = mask_mode
|
||||||
if len(mask_char) > 1:
|
if len(mask_char) > 1:
|
||||||
raise MaskingEditException('Masks of more than one character are not supported!')
|
raise MaskingEditException('Masks of more than one character are not supported!')
|
||||||
@@ -137,7 +137,7 @@ class MaskingEdit(urwid.Edit):
|
|||||||
focus.
|
focus.
|
||||||
"""
|
"""
|
||||||
# If we aren't masking anything ATM, then act like an Edit. No problems.
|
# If we aren't masking anything ATM, then act like an Edit. No problems.
|
||||||
if self.mask_mode == "off" or (self.mask_mode == 'on_focus' and focus == True):
|
if self.mask_mode == "off" or (self.mask_mode == 'no_focus' and focus == True):
|
||||||
canv = self.__super.render((maxcol,),focus)
|
canv = self.__super.render((maxcol,),focus)
|
||||||
# The cache messes this thing up, because I am totally changing what
|
# The cache messes this thing up, because I am totally changing what
|
||||||
# is displayed.
|
# is displayed.
|
||||||
|
|||||||
@@ -54,11 +54,11 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
|
|||||||
|
|
||||||
use_static_dns_t = language['use_static_dns']
|
use_static_dns_t = language['use_static_dns']
|
||||||
use_global_dns_t = language['use_global_dns']
|
use_global_dns_t = language['use_global_dns']
|
||||||
dns_dom_t = ('editcp',language['dns_domain']+': ')
|
dns_dom_t = ('editcp',language['dns_domain']+': ')
|
||||||
search_dom_t = ('editcp',language['search_domain']+':')
|
search_dom_t = ('editcp',language['search_domain']+':')
|
||||||
dns1_t = ('editcp',language['dns']+ ' ' + language['1']+':'+' '*8)
|
dns1_t = ('editcp',language['dns']+ ' ' + language['1']+':'+' '*8)
|
||||||
dns2_t = ('editcp',language['dns']+ ' ' + language['2']+':'+' '*8)
|
dns2_t = ('editcp',language['dns']+ ' ' + language['2']+':'+' '*8)
|
||||||
dns3_t = ('editcp',language['dns']+ ' ' + language['3']+':'+' '*8)
|
dns3_t = ('editcp',language['dns']+ ' ' + language['3']+':'+' '*8)
|
||||||
|
|
||||||
cancel_t = 'Cancel'
|
cancel_t = 'Cancel'
|
||||||
ok_t = 'OK'
|
ok_t = 'OK'
|
||||||
@@ -105,7 +105,7 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
|
|||||||
|
|
||||||
self._listbox = urwid.ListBox(walker)
|
self._listbox = urwid.ListBox(walker)
|
||||||
#self._frame = urwid.Frame(self._listbox)
|
#self._frame = urwid.Frame(self._listbox)
|
||||||
self._frame = urwid.Frame(self._listbox)
|
self._frame = urwid.Frame(self._listbox,footer=self.button_cols)
|
||||||
self.__super.__init__(self._frame)
|
self.__super.__init__(self._frame)
|
||||||
|
|
||||||
|
|
||||||
@@ -192,7 +192,12 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
|
|||||||
self.overlay.mouse_event( dim,
|
self.overlay.mouse_event( dim,
|
||||||
event, button, col, row,
|
event, button, col, row,
|
||||||
focus=True)
|
focus=True)
|
||||||
self.overlay.keypress(dim, k)
|
k = self.overlay.keypress(dim, k)
|
||||||
|
if k in ('up','page up'):
|
||||||
|
self._w.set_focus('body')
|
||||||
|
elif k in ('down','page down'):
|
||||||
|
self._w.set_focus('footer')
|
||||||
|
|
||||||
if "window resize" in keys:
|
if "window resize" in keys:
|
||||||
dim = ui.get_cols_rows()
|
dim = ui.get_cols_rows()
|
||||||
if "esc" in keys or 'Q' in keys:
|
if "esc" in keys or 'Q' in keys:
|
||||||
@@ -204,6 +209,7 @@ class AdvancedSettingsDialog(urwid.WidgetWrap):
|
|||||||
if self.CANCEL_PRESSED:
|
if self.CANCEL_PRESSED:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class WiredSettingsDialog(AdvancedSettingsDialog):
|
class WiredSettingsDialog(AdvancedSettingsDialog):
|
||||||
def __init__(self,name):
|
def __init__(self,name):
|
||||||
global wired, daemon
|
global wired, daemon
|
||||||
@@ -212,7 +218,6 @@ class WiredSettingsDialog(AdvancedSettingsDialog):
|
|||||||
#self.cur_default =
|
#self.cur_default =
|
||||||
# Add widgets to listbox
|
# Add widgets to listbox
|
||||||
self._w.body.body.append(self.set_default)
|
self._w.body.body.append(self.set_default)
|
||||||
self._w.body.body.append(self.button_cols)
|
|
||||||
|
|
||||||
self.prof_name = name
|
self.prof_name = name
|
||||||
title = ">"+language['configuring_wired'].replace('$A',self.prof_name)
|
title = ">"+language['configuring_wired'].replace('$A',self.prof_name)
|
||||||
@@ -265,16 +270,19 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
|
|||||||
self.networkID = networkID
|
self.networkID = networkID
|
||||||
global_settings_t = language['global_settings']
|
global_settings_t = language['global_settings']
|
||||||
encryption_t = language['use_encryption']
|
encryption_t = language['use_encryption']
|
||||||
|
autoconnect_t = language['automatic_connect']
|
||||||
|
|
||||||
self.global_settings_chkbox = urwid.CheckBox(global_settings_t)
|
self.global_settings_chkbox = urwid.CheckBox(global_settings_t)
|
||||||
self.encryption_chkbox = urwid.CheckBox(encryption_t,on_state_change=self.encryption_toggle)
|
self.encryption_chkbox = urwid.CheckBox(encryption_t,on_state_change=self.encryption_toggle)
|
||||||
self.encryption_combo = ComboBox(callback=self.combo_on_change)
|
self.encryption_combo = ComboBox(callback=self.combo_on_change)
|
||||||
|
self.autoconnect_chkbox = urwid.CheckBox(autoconnect_t)
|
||||||
self.pile_encrypt = None
|
self.pile_encrypt = None
|
||||||
# _w is a Frame, _w.body is a ListBox, _w.body.body is the ListWalker :-)
|
# _w is a Frame, _w.body is a ListBox, _w.body.body is the ListWalker :-)
|
||||||
self._w.body.body.append(self.global_settings_chkbox)
|
self._listbox.body.append(urwid.Text(""))
|
||||||
self._w.body.body.append(self.encryption_chkbox)
|
self._listbox.body.append(self.global_settings_chkbox)
|
||||||
self._w.body.body.append(self.encryption_combo)
|
self._listbox.body.append(self.autoconnect_chkbox)
|
||||||
self._w.body.body.append(self.button_cols)
|
self._listbox.body.append(self.encryption_chkbox)
|
||||||
|
self._listbox.body.append(self.encryption_combo)
|
||||||
self.encrypt_types = misc.LoadEncryptionMethods()
|
self.encrypt_types = misc.LoadEncryptionMethods()
|
||||||
self.set_values()
|
self.set_values()
|
||||||
|
|
||||||
@@ -306,6 +314,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
|
|||||||
self.dns_dom_edit.set_edit_text(self.format_entry(networkID, "dns_domain"))
|
self.dns_dom_edit.set_edit_text(self.format_entry(networkID, "dns_domain"))
|
||||||
self.search_dom_edit.set_edit_text(self.format_entry(networkID, "search_domain"))
|
self.search_dom_edit.set_edit_text(self.format_entry(networkID, "search_domain"))
|
||||||
|
|
||||||
|
self.autoconnect_chkbox.set_state(to_bool(self.format_entry(networkID, "automatic")))
|
||||||
|
|
||||||
#self.reset_static_checkboxes()
|
#self.reset_static_checkboxes()
|
||||||
self.encryption_chkbox.set_state(bool(wireless.GetWirelessProperty(networkID,
|
self.encryption_chkbox.set_state(bool(wireless.GetWirelessProperty(networkID,
|
||||||
@@ -367,6 +376,10 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
|
|||||||
#print "no encryption specified..."
|
#print "no encryption specified..."
|
||||||
self.set_net_prop("enctype", "None")
|
self.set_net_prop("enctype", "None")
|
||||||
AdvancedSettingsDialog.save_settings(self)
|
AdvancedSettingsDialog.save_settings(self)
|
||||||
|
|
||||||
|
# Save the autoconnect setting. This is not where it originally was
|
||||||
|
# in the GTK UI.
|
||||||
|
self.set_net_prop("automatic",self.autoconnect_chkbox.get_state())
|
||||||
|
|
||||||
if self.global_settings_chkbox.get_state():
|
if self.global_settings_chkbox.get_state():
|
||||||
self.set_net_prop('use_settings_globally', True)
|
self.set_net_prop('use_settings_globally', True)
|
||||||
@@ -385,7 +398,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
|
|||||||
self.encryption_info = {}
|
self.encryption_info = {}
|
||||||
|
|
||||||
if self._w.body.body.__contains__(self.pile_encrypt):
|
if self._w.body.body.__contains__(self.pile_encrypt):
|
||||||
self._w.body.body.pop(self._w.body.body.__len__()-2)
|
self._w.body.body.pop(self._w.body.body.__len__()-1)
|
||||||
|
|
||||||
# If nothing is selected, select the first entry.
|
# If nothing is selected, select the first entry.
|
||||||
if ID == -1:
|
if ID == -1:
|
||||||
@@ -397,9 +410,9 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
|
|||||||
for x in opts:
|
for x in opts:
|
||||||
edit = None
|
edit = None
|
||||||
if language.has_key(opts[x][0]):
|
if language.has_key(opts[x][0]):
|
||||||
edit = MaskingEdit(('editcp',language[opts[x][0].lower().replace(' ','_')]+': '),mask_mode='on_focus')
|
edit = MaskingEdit(('editcp',language[opts[x][0].lower().replace(' ','_')]+': '),mask_mode='no_focus')
|
||||||
else:
|
else:
|
||||||
edit = MaskingEdit(('editcp',opts[x][0].replace('_',' ')+': '),mask_mode='on_focus')
|
edit = MaskingEdit(('editcp',opts[x][0].replace('_',' ')+': '),mask_mode='no_focus')
|
||||||
theList.append(edit)
|
theList.append(edit)
|
||||||
# Add the data to any array, so that the information
|
# Add the data to any array, so that the information
|
||||||
# can be easily accessed by giving the name of the wanted
|
# can be easily accessed by giving the name of the wanted
|
||||||
@@ -410,7 +423,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog):
|
|||||||
wireless.GetWirelessProperty(self.networkID, opts[x][1])))
|
wireless.GetWirelessProperty(self.networkID, opts[x][1])))
|
||||||
|
|
||||||
self.pile_encrypt = DynWrap(urwid.Pile(theList),attrs=('editbx','editnfc'))
|
self.pile_encrypt = DynWrap(urwid.Pile(theList),attrs=('editbx','editnfc'))
|
||||||
self._w.body.body.insert(self._w.body.body.__len__()-1,self.pile_encrypt)
|
self._w.body.body.insert(self._w.body.body.__len__(),self.pile_encrypt)
|
||||||
#self._w.body.body.append(self.pile_encrypt)
|
#self._w.body.body.append(self.pile_encrypt)
|
||||||
|
|
||||||
def prerun(self,ui,dim,display):
|
def prerun(self,ui,dim,display):
|
||||||
|
|||||||
@@ -86,32 +86,28 @@ class wrap_exceptions:
|
|||||||
try:
|
try:
|
||||||
return f(*args, **kargs)
|
return f(*args, **kargs)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
gobject.source_remove(redraw_tag)
|
#gobject.source_remove(redraw_tag)
|
||||||
loop.quit()
|
loop.quit()
|
||||||
ui.stop()
|
ui.stop()
|
||||||
print "\n"+language['terminated']
|
print "\n"+language['terminated']
|
||||||
#raise
|
#raise
|
||||||
except DBusException:
|
except DBusException:
|
||||||
gobject.source_remove(redraw_tag)
|
#gobject.source_remove(redraw_tag)
|
||||||
loop.quit()
|
loop.quit()
|
||||||
ui.stop()
|
ui.stop()
|
||||||
print "\n"+language['dbus_fail']
|
print "\n"+language['dbus_fail']
|
||||||
raise
|
raise
|
||||||
except :
|
except :
|
||||||
# If the UI isn't inactive (redraw_tag wouldn't normally be
|
# Quit the loop
|
||||||
# set), then don't try to stop it, just gracefully die.
|
if 'loop' in locals():
|
||||||
if redraw_tag != -1:
|
|
||||||
# Remove update_ui from the event queue
|
|
||||||
gobject.source_remove(redraw_tag)
|
|
||||||
# Quit the loop
|
|
||||||
loop.quit()
|
loop.quit()
|
||||||
# Zap the screen
|
# Zap the screen
|
||||||
ui.stop()
|
ui.stop()
|
||||||
# Print out standard notification:
|
# Print out standard notification:
|
||||||
print "\n" + language['exception']
|
print "\n" + language['exception']
|
||||||
# Flush the buffer so that the notification is always above the
|
# Flush the buffer so that the notification is always above the
|
||||||
# backtrace
|
# backtrace
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
# Raise the exception
|
# Raise the exception
|
||||||
#sleep(2)
|
#sleep(2)
|
||||||
raise
|
raise
|
||||||
@@ -897,16 +893,16 @@ def main():
|
|||||||
('green','dark green','default'),
|
('green','dark green','default'),
|
||||||
('blue','dark blue','default'),
|
('blue','dark blue','default'),
|
||||||
('red','dark red','default'),
|
('red','dark red','default'),
|
||||||
('bold','white','default','bold')])
|
('bold','white','black','bold')])
|
||||||
# This is a wrapper around a function that calls another a function that is a
|
# This is a wrapper around a function that calls another a function that is a
|
||||||
# wrapper around a infinite loop. Fun.
|
# wrapper around a infinite loop. Fun.
|
||||||
|
urwid.set_encoding('utf8')
|
||||||
ui.run_wrapper(run)
|
ui.run_wrapper(run)
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
global loop,redraw_tag
|
global loop
|
||||||
|
|
||||||
ui.set_mouse_tracking()
|
ui.set_mouse_tracking()
|
||||||
redraw_tag = -1
|
|
||||||
app = appGUI()
|
app = appGUI()
|
||||||
|
|
||||||
# Connect signals and whatnot to UI screen control functions
|
# Connect signals and whatnot to UI screen control functions
|
||||||
@@ -919,7 +915,7 @@ def run():
|
|||||||
'org.wicd.daemon')
|
'org.wicd.daemon')
|
||||||
loop = gobject.MainLoop()
|
loop = gobject.MainLoop()
|
||||||
# Update what the interface looks like as an idle function
|
# Update what the interface looks like as an idle function
|
||||||
redraw_tag = gobject.idle_add(app.update_ui)
|
gobject.idle_add(app.update_ui)
|
||||||
# Update the connection status on the bottom every 1.5 s.
|
# Update the connection status on the bottom every 1.5 s.
|
||||||
gobject.timeout_add(1500,app.update_status)
|
gobject.timeout_add(1500,app.update_status)
|
||||||
gobject.idle_add(app.idle_incr)
|
gobject.idle_add(app.idle_incr)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
# This is defined in /usr/lib/python2.5/site-packages/wicd/wpath.py
|
# This is defined in /usr/lib/python2.5/site-packages/wicd/wpath.py
|
||||||
PIDFILE="%PIDFILE%"
|
PIDFILE="%PIDFILE%"
|
||||||
|
DAEMON="%SBIN%wicd"
|
||||||
|
|
||||||
# Define start and stop functions
|
# Define start and stop functions
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ wicd_start() {
|
|||||||
echo "$PIDFILE and try again..."
|
echo "$PIDFILE and try again..."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
echo "Starting wicd daemon..."
|
echo "Starting wicd daemon: $DAEMON"
|
||||||
wicd 2>/dev/null 1>&2
|
wicd 2>/dev/null 1>&2
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,20 +64,15 @@ Bring up instructions on how to edit the scripts. I have implemented a way to d
|
|||||||
Raise the Ad-Hoc network creation dialog
|
Raise the Ad-Hoc network creation dialog
|
||||||
|
|
||||||
.SH "FILES"
|
.SH "FILES"
|
||||||
These are not used yet.
|
|
||||||
.TP
|
.TP
|
||||||
.I ~/.wicd/WHEREAREMYFILES
|
.I ~/.wicd/WHEREAREMYFILES
|
||||||
Reminder that your network configuration files are not here ;-)
|
Reminder that your network configuration files are not here ;-)
|
||||||
.TP
|
.PP
|
||||||
.I %LIB%keymap.py
|
These following are not used yet:
|
||||||
Tentative location of the system keymap
|
|
||||||
.TP
|
.TP
|
||||||
.I %LIB%colors.py
|
.I %LIB%colors.py
|
||||||
Tentative location of the system color schemes
|
Tentative location of the system color schemes
|
||||||
.TP
|
.TP
|
||||||
.I ~/.wicd/keymap.py
|
|
||||||
Custom keybindings. Also where you can (later) disable the mouse.
|
|
||||||
.TP
|
|
||||||
.I ~/.wicd/colors.py
|
.I ~/.wicd/colors.py
|
||||||
Custom color schemes.
|
Custom color schemes.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
@@ -87,7 +82,7 @@ Custom color schemes.
|
|||||||
.SH BUGS
|
.SH BUGS
|
||||||
Probably lots. ;-)
|
Probably lots. ;-)
|
||||||
|
|
||||||
If you happen to find one, ask about it on #wicd on freenode, or submit a bug report to http://launchpad.net/wicd, branch experimental-nacl.
|
If you happen to find one, ask about it on #wicd on freenode, or submit a bug report to http://launchpad.net/wicd.
|
||||||
|
|
||||||
.SH WICD-CURSES AUTHOR
|
.SH WICD-CURSES AUTHOR
|
||||||
Andrew Psaltis <ampsaltis@gmail.com>
|
Andrew Psaltis <ampsaltis@gmail.com>
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ Adam Blackburn <compwiz18@gmail.com>
|
|||||||
.br
|
.br
|
||||||
Dan O'Reilly <oreilldf@gmail.com>
|
Dan O'Reilly <oreilldf@gmail.com>
|
||||||
.br
|
.br
|
||||||
Andrew Psaltis <insertmail@here> (curses client)
|
Andrew Psaltis <ampsaltis@gmail.com> (curses client)
|
||||||
|
|
||||||
.SH MANPAGE AUTHOR
|
.SH MANPAGE AUTHOR
|
||||||
Robby Workman <rworkman@slackware.com>
|
Robby Workman <rworkman@slackware.com>
|
||||||
|
|||||||
9
setup.py
9
setup.py
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright (C) 2007 - 2008 Adam Blackburn
|
# Copyright (C) 2007 - 2009 Adam Blackburn
|
||||||
# Copyright (C) 2007 - 2008 Dan O'Reilly
|
# Copyright (C) 2007 - 2009 Dan O'Reilly
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License Version 2 as
|
||||||
@@ -25,9 +25,10 @@ import subprocess
|
|||||||
|
|
||||||
# Be sure to keep this updated!
|
# Be sure to keep this updated!
|
||||||
# VERSIONNUMBER
|
# VERSIONNUMBER
|
||||||
VERSION_NUM = '1.6.0'
|
VERSION_NUM = '1.6.0a1'
|
||||||
|
# REVISION_NUM is automatically updated
|
||||||
REVISION_NUM = 'unknown'
|
REVISION_NUM = 'unknown'
|
||||||
CURSES_REVNO = 'r273'
|
CURSES_REVNO = 'r277'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not os.path.exists('vcsinfo.py'):
|
if not os.path.exists('vcsinfo.py'):
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ from wicd.wnettools import *
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
|
# Regular expressions for wpa_cli output
|
||||||
|
auth_patten = re.compile('.*wpa_state=(.*?)\n', wnettools.__re_mode)
|
||||||
NAME = "external"
|
NAME = "external"
|
||||||
UPDATE_INTERVAL = 5
|
UPDATE_INTERVAL = 5
|
||||||
DESCRIPTION = """External app (original) backend
|
DESCRIPTION = """External app (original) backend
|
||||||
@@ -49,30 +49,6 @@ it doesn't require any third party libraries and may be
|
|||||||
more stable for some set ups.
|
more stable for some set ups.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# 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
|
|
||||||
essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\n', re.I | re.M | re.S)
|
|
||||||
ap_mac_pattern = re.compile('.*Address: (.*?)\n', re.I | re.M | re.S)
|
|
||||||
channel_pattern = re.compile('.*Channel:? ?(\d\d?)', re.I | re.M | re.S)
|
|
||||||
strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', re.I | re.M | re.S)
|
|
||||||
# These next two look a lot a like, altstrength is for Signal level = xx/100,
|
|
||||||
# which is just an alternate way of displaying link quality, signaldbm is
|
|
||||||
# for displaying actual signal strength (-xx dBm).
|
|
||||||
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)', re.I | re.M | re.S)
|
|
||||||
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', re.I | re.M | re.S)
|
|
||||||
mode_pattern = re.compile('.*Mode:(.*?)\n', re.I | re.M | re.S)
|
|
||||||
freq_pattern = re.compile('.*Frequency:(.*?)\n', re.I | re.M | re.S)
|
|
||||||
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)', re.S)
|
|
||||||
bssid_pattern = re.compile('.*Access Point: (([0-9A-Z]{2}:){5}[0-9A-Z]{2})', re.I | re.M | re.S)
|
|
||||||
|
|
||||||
wep_pattern = re.compile('.*Encryption key:(.*?)\n', re.I | re.M | re.S)
|
|
||||||
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)
|
|
||||||
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'
|
RALINK_DRIVER = 'ralink legacy'
|
||||||
|
|
||||||
|
|
||||||
@@ -94,54 +70,6 @@ class Interface(wnettools.BaseInterface):
|
|||||||
wnettools.BaseInterface.__init__(self, iface, verbose)
|
wnettools.BaseInterface.__init__(self, iface, verbose)
|
||||||
self.Check()
|
self.Check()
|
||||||
|
|
||||||
def GetIP(self, ifconfig=""):
|
|
||||||
""" Get the IP address of the interface.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The IP address of the interface in dotted quad form.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not ifconfig:
|
|
||||||
cmd = 'ifconfig ' + self.iface
|
|
||||||
if self.verbose: print cmd
|
|
||||||
output = misc.Run(cmd)
|
|
||||||
else:
|
|
||||||
output = ifconfig
|
|
||||||
return misc.RunRegex(ip_pattern, output)
|
|
||||||
|
|
||||||
def IsUp(self, ifconfig=None):
|
|
||||||
""" Determines if the interface is up.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if the interface is up, False otherwise.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not self.iface: return False
|
|
||||||
flags_file = '/sys/class/net/%s/flags' % self.iface
|
|
||||||
try:
|
|
||||||
flags = open(flags_file, "r").read().strip()
|
|
||||||
except IOError:
|
|
||||||
print "Could not open %s, using ifconfig to determine status" % flags_file
|
|
||||||
return self._slow_is_up(ifconfig)
|
|
||||||
return bool(int(flags, 16) & 1)
|
|
||||||
|
|
||||||
|
|
||||||
def _slow_is_up(self, ifconfig=None):
|
|
||||||
""" Determine if an interface is up using ifconfig. """
|
|
||||||
if not ifconfig:
|
|
||||||
cmd = "ifconfig " + self.iface
|
|
||||||
if self.verbose: print cmd
|
|
||||||
output = misc.Run(cmd)
|
|
||||||
else:
|
|
||||||
output = ifconfig
|
|
||||||
lines = output.split('\n')
|
|
||||||
if len(lines) < 5:
|
|
||||||
return False
|
|
||||||
for line in lines[1:4]:
|
|
||||||
if line.strip().startswith('UP'):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class WiredInterface(Interface, wnettools.BaseWiredInterface):
|
class WiredInterface(Interface, wnettools.BaseWiredInterface):
|
||||||
""" Control a wired network interface. """
|
""" Control a wired network interface. """
|
||||||
@@ -156,97 +84,6 @@ class WiredInterface(Interface, wnettools.BaseWiredInterface):
|
|||||||
wnettools.BaseWiredInterface.__init__(self, iface, verbose)
|
wnettools.BaseWiredInterface.__init__(self, iface, verbose)
|
||||||
Interface.__init__(self, iface, verbose)
|
Interface.__init__(self, iface, verbose)
|
||||||
|
|
||||||
def GetPluggedIn(self):
|
|
||||||
""" Get the current physical connection state.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if a link is detected, False otherwise.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not self.iface:
|
|
||||||
return False
|
|
||||||
# check for link using /sys/class/net/iface/carrier
|
|
||||||
# is usually more accurate
|
|
||||||
sys_device = '/sys/class/net/%s/' % self.iface
|
|
||||||
carrier_path = sys_device + 'carrier'
|
|
||||||
if not self.IsUp():
|
|
||||||
MAX_TRIES = 3
|
|
||||||
tries = 0
|
|
||||||
self.Up()
|
|
||||||
while True:
|
|
||||||
tries += 1
|
|
||||||
time.sleep(2)
|
|
||||||
if self.IsUp() or tries > MAX_TRIES: break
|
|
||||||
|
|
||||||
if os.path.exists(carrier_path):
|
|
||||||
carrier = open(carrier_path, 'r')
|
|
||||||
try:
|
|
||||||
link = carrier.read().strip()
|
|
||||||
link = int(link)
|
|
||||||
if link == 1:
|
|
||||||
return True
|
|
||||||
elif link == 0:
|
|
||||||
return False
|
|
||||||
except (IOError, ValueError, TypeError):
|
|
||||||
print 'Error checking link using /sys/class/net/%s/carrier' % self.iface
|
|
||||||
|
|
||||||
if self.ethtool_cmd and self.link_detect in [misc.ETHTOOL, misc.AUTO]:
|
|
||||||
return self._eth_get_plugged_in()
|
|
||||||
elif self.miitool_cmd and self.link_detect in [misc.MIITOOL, misc.AUTO]:
|
|
||||||
return self._mii_get_plugged_in()
|
|
||||||
else:
|
|
||||||
print ('Error: No way of checking for a wired connection. Make ' +
|
|
||||||
'sure that either mii-tool or ethtool is installed.')
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _eth_get_plugged_in(self):
|
|
||||||
""" Use ethtool to determine the physical connection state.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if a link is detected, False otherwise.
|
|
||||||
|
|
||||||
"""
|
|
||||||
cmd = "%s %s" % (self.ethtool_cmd, self.iface)
|
|
||||||
if not self.IsUp():
|
|
||||||
print 'Wired Interface is down, putting it up'
|
|
||||||
self.Up()
|
|
||||||
time.sleep(6)
|
|
||||||
if self.verbose: print cmd
|
|
||||||
tool_data = misc.Run(cmd, include_stderr=True)
|
|
||||||
if misc.RunRegex(re.compile('(Link detected: yes)', re.I | re.M | re.S),
|
|
||||||
tool_data):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _mii_get_plugged_in(self):
|
|
||||||
""" Use mii-tool to determine the physical connection state.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if a link is detected, False otherwise.
|
|
||||||
|
|
||||||
"""
|
|
||||||
cmd = "%s %s" % (self.miitool_cmd, self.iface)
|
|
||||||
if self.verbose: print cmd
|
|
||||||
tool_data = misc.Run(cmd, include_stderr=True)
|
|
||||||
if misc.RunRegex(re.compile('(Invalid argument)', re.I | re.M | re.S),
|
|
||||||
tool_data) is not None:
|
|
||||||
print 'Wired Interface is down, putting it up'
|
|
||||||
self.Up()
|
|
||||||
time.sleep(4)
|
|
||||||
if self.verbose: print cmd
|
|
||||||
tool_data = misc.Run(cmd, include_stderr=True)
|
|
||||||
|
|
||||||
if misc.RunRegex(re.compile('(link ok)', re.I | re.M | re.S),
|
|
||||||
tool_data) is not None:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
|
class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
|
||||||
""" Control a wireless network interface. """
|
""" Control a wireless network interface. """
|
||||||
@@ -262,265 +99,3 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
|
|||||||
wpa_driver)
|
wpa_driver)
|
||||||
Interface.__init__(self, iface, verbose)
|
Interface.__init__(self, iface, verbose)
|
||||||
|
|
||||||
def GetNetworks(self):
|
|
||||||
""" Get a list of available wireless networks.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A list containing available wireless networks.
|
|
||||||
|
|
||||||
"""
|
|
||||||
cmd = 'iwlist ' + self.iface + ' scan'
|
|
||||||
if self.verbose: print cmd
|
|
||||||
results = misc.Run(cmd)
|
|
||||||
# Split the networks apart, using Cell as our split point
|
|
||||||
# this way we can look at only one network at a time.
|
|
||||||
# The spaces around ' Cell ' are to minimize the chance that someone
|
|
||||||
# has an essid named Cell...
|
|
||||||
networks = results.split( ' Cell ' )
|
|
||||||
|
|
||||||
# Get available network info from iwpriv get_site_survey
|
|
||||||
# if we're using a ralink card (needed to get encryption info)
|
|
||||||
if self.wpa_driver == RALINK_DRIVER:
|
|
||||||
ralink_info = self._GetRalinkInfo()
|
|
||||||
else:
|
|
||||||
ralink_info = None
|
|
||||||
|
|
||||||
# An array for the access points
|
|
||||||
access_points = []
|
|
||||||
for cell in networks:
|
|
||||||
# Only use sections where there is an ESSID.
|
|
||||||
if 'ESSID:' in cell:
|
|
||||||
# Add this network to the list of networks
|
|
||||||
entry = self._ParseAccessPoint(cell, ralink_info)
|
|
||||||
if entry is not None:
|
|
||||||
access_points.append(entry)
|
|
||||||
|
|
||||||
return access_points
|
|
||||||
|
|
||||||
def _ParseAccessPoint(self, cell, ralink_info):
|
|
||||||
""" Parse a single cell from the output of iwlist.
|
|
||||||
|
|
||||||
Keyword arguments:
|
|
||||||
cell -- string containing the cell information
|
|
||||||
ralink_info -- string contating network information needed
|
|
||||||
for ralink cards.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A dictionary containing the cell networks properties.
|
|
||||||
|
|
||||||
"""
|
|
||||||
ap = {}
|
|
||||||
ap['essid'] = misc.RunRegex(essid_pattern, cell)
|
|
||||||
try:
|
|
||||||
ap['essid'] = misc.to_unicode(ap['essid'])
|
|
||||||
except (UnicodeDecodeError, UnicodeEncodeError):
|
|
||||||
print 'Unicode problem with current network essid, ignoring!!'
|
|
||||||
return None
|
|
||||||
if ap['essid'] in ['<hidden>', ""]:
|
|
||||||
ap['hidden'] = True
|
|
||||||
ap['essid'] = "<hidden>"
|
|
||||||
else:
|
|
||||||
ap['hidden'] = False
|
|
||||||
|
|
||||||
# Channel - For cards that don't have a channel number,
|
|
||||||
# convert the frequency.
|
|
||||||
ap['channel'] = misc.RunRegex(channel_pattern, cell)
|
|
||||||
if ap['channel'] == None:
|
|
||||||
freq = misc.RunRegex(freq_pattern, cell)
|
|
||||||
ap['channel'] = self._FreqToChannel(freq)
|
|
||||||
|
|
||||||
# BSSID
|
|
||||||
ap['bssid'] = misc.RunRegex(ap_mac_pattern, cell)
|
|
||||||
|
|
||||||
# Mode
|
|
||||||
ap['mode'] = misc.RunRegex(mode_pattern, cell)
|
|
||||||
|
|
||||||
# Break off here if we're using a ralink card
|
|
||||||
if self.wpa_driver == RALINK_DRIVER:
|
|
||||||
ap = self._ParseRalinkAccessPoint(ap, ralink_info, cell)
|
|
||||||
elif misc.RunRegex(wep_pattern, cell) == 'on':
|
|
||||||
# Encryption - Default to WEP
|
|
||||||
ap['encryption'] = True
|
|
||||||
ap['encryption_method'] = 'WEP'
|
|
||||||
|
|
||||||
if misc.RunRegex(wpa1_pattern, cell) == 'WPA Version 1':
|
|
||||||
ap['encryption_method'] = 'WPA'
|
|
||||||
|
|
||||||
if misc.RunRegex(altwpa_pattern, cell) == 'wpa_ie':
|
|
||||||
ap['encryption_method'] = 'WPA'
|
|
||||||
|
|
||||||
if misc.RunRegex(wpa2_pattern, cell) == 'WPA2':
|
|
||||||
ap['encryption_method'] = 'WPA2'
|
|
||||||
else:
|
|
||||||
ap['encryption'] = False
|
|
||||||
|
|
||||||
# Link Quality
|
|
||||||
# Set strength to -1 if the quality is not found
|
|
||||||
|
|
||||||
# more of the patch from
|
|
||||||
# https://bugs.launchpad.net/wicd/+bug/175104
|
|
||||||
if (strength_pattern.match(cell)):
|
|
||||||
[(strength, max_strength)] = strength_pattern.findall(cell)
|
|
||||||
if max_strength:
|
|
||||||
ap["quality"] = 100 * int(strength) // int(max_strength)
|
|
||||||
else:
|
|
||||||
ap["quality"] = int(strength)
|
|
||||||
elif misc.RunRegex(altstrength_pattern,cell):
|
|
||||||
ap['quality'] = misc.RunRegex(altstrength_pattern, cell)
|
|
||||||
else:
|
|
||||||
ap['quality'] = -1
|
|
||||||
|
|
||||||
# Signal Strength (only used if user doesn't want link
|
|
||||||
# quality displayed or it isn't found)
|
|
||||||
if misc.RunRegex(signaldbm_pattern, cell):
|
|
||||||
ap['strength'] = misc.RunRegex(signaldbm_pattern, cell)
|
|
||||||
elif self.wpa_driver != RALINK_DRIVER: # This is already set for ralink
|
|
||||||
ap['strength'] = -1
|
|
||||||
|
|
||||||
return ap
|
|
||||||
|
|
||||||
def ValidateAuthentication(self, auth_time):
|
|
||||||
""" Validate WPA authentication.
|
|
||||||
|
|
||||||
Validate that the wpa_supplicant authentication
|
|
||||||
process was successful.
|
|
||||||
|
|
||||||
NOTE: It's possible this could return False,
|
|
||||||
though in reality wpa_supplicant just isn't
|
|
||||||
finished yet.
|
|
||||||
|
|
||||||
Keyword arguments:
|
|
||||||
auth_time -- The time at which authentication began.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if wpa_supplicant authenticated succesfully,
|
|
||||||
False otherwise.
|
|
||||||
|
|
||||||
"""
|
|
||||||
# Right now there's no way to do this for these drivers
|
|
||||||
if self.wpa_driver == RALINK_DRIVER or not self.wpa_cli_cmd:
|
|
||||||
return True
|
|
||||||
|
|
||||||
MAX_TIME = 35
|
|
||||||
MAX_DISCONNECTED_TIME = 3
|
|
||||||
disconnected_time = 0
|
|
||||||
while (time.time() - auth_time) < MAX_TIME:
|
|
||||||
cmd = '%s -i %s status' % (self.wpa_cli_cmd, self.iface)
|
|
||||||
output = misc.Run(cmd)
|
|
||||||
result = misc.RunRegex(auth_pattern, output)
|
|
||||||
if self.verbose:
|
|
||||||
print 'WPA_CLI RESULT IS', result
|
|
||||||
|
|
||||||
if not result:
|
|
||||||
return False
|
|
||||||
if result == "COMPLETED":
|
|
||||||
return True
|
|
||||||
elif result == "DISCONNECTED":
|
|
||||||
disconnected_time += 1
|
|
||||||
if disconnected_time > MAX_DISCONNECTED_TIME:
|
|
||||||
disconnected_time = 0
|
|
||||||
# Force a rescan to get wpa_supplicant moving again.
|
|
||||||
self._ForceSupplicantScan()
|
|
||||||
MAX_TIME += 5
|
|
||||||
else:
|
|
||||||
disconnected_time = 0
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
print 'wpa_supplicant authentication may have failed.'
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _ForceSupplicantScan(self):
|
|
||||||
""" Force wpa_supplicant to rescan available networks.
|
|
||||||
|
|
||||||
This function forces wpa_supplicant to rescan.
|
|
||||||
This works around authentication validation sometimes failing for
|
|
||||||
wpa_supplicant because it remains in a DISCONNECTED state for
|
|
||||||
quite a while, after which a rescan is required, and then
|
|
||||||
attempting to authenticate. This whole process takes a long
|
|
||||||
time, so we manually speed it up if we see it happening.
|
|
||||||
|
|
||||||
"""
|
|
||||||
print 'wpa_supplicant rescan forced...'
|
|
||||||
cmd = 'wpa_cli -i' + self.iface + ' scan'
|
|
||||||
misc.Run(cmd)
|
|
||||||
|
|
||||||
def StopWPA(self):
|
|
||||||
""" Terminates wpa using wpa_cli"""
|
|
||||||
cmd = 'wpa_cli -i %s terminate' % self.iface
|
|
||||||
if self.verbose: print cmd
|
|
||||||
misc.Run(cmd)
|
|
||||||
|
|
||||||
def GetBSSID(self, iwconfig=None):
|
|
||||||
""" Get the MAC address for the interface. """
|
|
||||||
if not iwconfig:
|
|
||||||
cmd = 'iwconfig ' + self.iface
|
|
||||||
if self.verbose: print cmd
|
|
||||||
output = misc.Run(cmd)
|
|
||||||
else:
|
|
||||||
output = iwconfig
|
|
||||||
|
|
||||||
bssid = misc.RunRegex(bssid_pattern, output)
|
|
||||||
return bssid
|
|
||||||
|
|
||||||
def GetSignalStrength(self, iwconfig=None):
|
|
||||||
""" Get the signal strength of the current network.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The signal strength.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not iwconfig:
|
|
||||||
cmd = 'iwconfig ' + self.iface
|
|
||||||
if self.verbose: print cmd
|
|
||||||
output = misc.Run(cmd)
|
|
||||||
else:
|
|
||||||
output = iwconfig
|
|
||||||
|
|
||||||
[(strength, max_strength)] = strength_pattern.findall(output)
|
|
||||||
if max_strength and strength:
|
|
||||||
if int(max_strength) != 0:
|
|
||||||
return 100 * int(strength) // int(max_strength)
|
|
||||||
else:
|
|
||||||
# Prevent a divide by zero error.
|
|
||||||
strength = int(strength)
|
|
||||||
|
|
||||||
if strength is None:
|
|
||||||
strength = misc.RunRegex(altstrength_pattern, output)
|
|
||||||
|
|
||||||
return strength
|
|
||||||
|
|
||||||
def GetDBMStrength(self, iwconfig=None):
|
|
||||||
""" Get the dBm signal strength of the current network.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The dBm signal strength.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not iwconfig:
|
|
||||||
cmd = 'iwconfig ' + self.iface
|
|
||||||
if self.verbose: print cmd
|
|
||||||
output = misc.Run(cmd)
|
|
||||||
else:
|
|
||||||
output = iwconfig
|
|
||||||
dbm_strength = misc.RunRegex(signaldbm_pattern, output)
|
|
||||||
return dbm_strength
|
|
||||||
|
|
||||||
def GetCurrentNetwork(self, iwconfig=None):
|
|
||||||
""" Get the essid of the current network.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The current network essid.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not iwconfig:
|
|
||||||
cmd = 'iwconfig ' + self.iface
|
|
||||||
if self.verbose: print cmd
|
|
||||||
output = misc.Run(cmd)
|
|
||||||
else:
|
|
||||||
output = iwconfig
|
|
||||||
network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',
|
|
||||||
re.I | re.M | re.S), output)
|
|
||||||
if network:
|
|
||||||
network = misc.to_unicode(network)
|
|
||||||
return network
|
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ from wicd import misc
|
|||||||
from wicd import wnettools
|
from wicd import wnettools
|
||||||
from wicd import wpath
|
from wicd import wpath
|
||||||
from wicd.wnettools import *
|
from wicd.wnettools import *
|
||||||
|
from wicd.wnettools import strength_pattern, altstrength_pattern, wep_pattern, \
|
||||||
|
signaldbm_pattern
|
||||||
|
|
||||||
import iwscan
|
import iwscan
|
||||||
import wpactrl
|
import wpactrl
|
||||||
@@ -58,14 +60,6 @@ Dependencies:
|
|||||||
python-wpactrl (http://projects.otaku42.de/wiki/PythonWpaCtrl)
|
python-wpactrl (http://projects.otaku42.de/wiki/PythonWpaCtrl)
|
||||||
python-iwscan (http://projects.otaku42.de/browser/python-iwscan/)"""
|
python-iwscan (http://projects.otaku42.de/browser/python-iwscan/)"""
|
||||||
|
|
||||||
strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)',
|
|
||||||
re.I | re.M | re.S)
|
|
||||||
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)',
|
|
||||||
re.I | re.M | re.S)
|
|
||||||
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)',
|
|
||||||
re.I | re.M | re.S)
|
|
||||||
wep_pattern = re.compile('.*Encryption key:(.*?)\n', re.I | re.M | re.S)
|
|
||||||
|
|
||||||
RALINK_DRIVER = 'ralink legacy'
|
RALINK_DRIVER = 'ralink legacy'
|
||||||
|
|
||||||
# Got these from /usr/include/linux/wireless.h
|
# Got these from /usr/include/linux/wireless.h
|
||||||
@@ -341,14 +335,16 @@ class WirelessInterface(Interface, wnettools.BaseWirelessInterface):
|
|||||||
def _connect_to_wpa_ctrl_iface(self):
|
def _connect_to_wpa_ctrl_iface(self):
|
||||||
""" Connect to the wpa ctrl interface. """
|
""" Connect to the wpa ctrl interface. """
|
||||||
ctrl_iface = '/var/run/wpa_supplicant'
|
ctrl_iface = '/var/run/wpa_supplicant'
|
||||||
try:
|
socket_loc = os.path.join(ctrl_iface, self.iface)
|
||||||
socket = [os.path.join(ctrl_iface, s) \
|
if os.path.exists(socket_loc):
|
||||||
for s in os.listdir(ctrl_iface) if s == self.iface][0]
|
try:
|
||||||
except OSError, error:
|
return wpactrl.WPACtrl(socket_loc)
|
||||||
print error
|
except wpactrl.error, e:
|
||||||
|
print "Couldn't open ctrl_interface: %s" % e
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
print "Couldn't find a wpa_supplicant ctrl_interface for iface %s" % self.iface
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return wpactrl.WPACtrl(socket)
|
|
||||||
|
|
||||||
def ValidateAuthentication(self, auth_time):
|
def ValidateAuthentication(self, auth_time):
|
||||||
""" Validate WPA authentication.
|
""" Validate WPA authentication.
|
||||||
|
|||||||
53
wicd/misc.py
53
wicd/misc.py
@@ -223,19 +223,34 @@ def ParseEncryption(network):
|
|||||||
"""
|
"""
|
||||||
enctemplate = open(wpath.encryption + network["enctype"])
|
enctemplate = open(wpath.encryption + network["enctype"])
|
||||||
template = enctemplate.readlines()
|
template = enctemplate.readlines()
|
||||||
# Set these to nothing so that we can hold them outside the loop
|
config_file = "ap_scan=1\n"
|
||||||
z = "ap_scan=1\n"
|
should_replace = False
|
||||||
# Loop through the lines in the template, selecting ones to use
|
for index, line in enumerate(template):
|
||||||
for y, x in enumerate(template):
|
if not should_replace:
|
||||||
x = x.strip("\n")
|
if line.strip().startswith('---'):
|
||||||
if y > 4:
|
should_replace = True
|
||||||
# replace values
|
else:
|
||||||
x = x.replace("$_SCAN","0")
|
if line.strip().startswith("}"):
|
||||||
for t in network:
|
# This is the last line, so we just write it.
|
||||||
# Don't bother if z's value is None cause it will cause errors
|
config_file = ''.join([config_file, line])
|
||||||
if Noneify(network[t]) is not None:
|
elif "$_" in line:
|
||||||
x = x.replace("$_" + str(t).upper(), str(network[t]))
|
cur_val = re.findall('\$_([A-Z0-9_]+)', line)
|
||||||
z = z + "\n" + x
|
if cur_val:
|
||||||
|
if cur_val[0] == 'SCAN':
|
||||||
|
#TODO should this be hardcoded?
|
||||||
|
line = line.replace("$_SCAN", "0")
|
||||||
|
config_file = ''.join([config_file, line])
|
||||||
|
else:
|
||||||
|
rep_val = network.get(cur_val[0].lower())
|
||||||
|
if rep_val:
|
||||||
|
line = line.replace("$_%s" % cur_val[0], rep_val)
|
||||||
|
config_file = ''.join([config_file, line])
|
||||||
|
else:
|
||||||
|
print "Ignoring template line: '%s'" % line
|
||||||
|
else:
|
||||||
|
print "Weird parsing error occurred"
|
||||||
|
else: # Just a regular entry.
|
||||||
|
config_file = ''.join([config_file, line])
|
||||||
|
|
||||||
# Write the data to the files then chmod them so they can't be read
|
# Write the data to the files then chmod them so they can't be read
|
||||||
# by normal users.
|
# by normal users.
|
||||||
@@ -244,7 +259,7 @@ def ParseEncryption(network):
|
|||||||
os.chown(wpath.networks + network["bssid"].replace(":", "").lower(), 0, 0)
|
os.chown(wpath.networks + network["bssid"].replace(":", "").lower(), 0, 0)
|
||||||
# We could do this above, but we'd like to read protect
|
# We could do this above, but we'd like to read protect
|
||||||
# them before we write, so that it can't be read.
|
# them before we write, so that it can't be read.
|
||||||
f.write(z)
|
f.write(config_file)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def LoadEncryptionMethods():
|
def LoadEncryptionMethods():
|
||||||
@@ -525,7 +540,7 @@ def get_language_list_gui():
|
|||||||
language['stop_showing_chooser'] = _('Stop Showing Autoconnect pop-up temporarily')
|
language['stop_showing_chooser'] = _('Stop Showing Autoconnect pop-up temporarily')
|
||||||
language['display_type_dialog'] = _('Use dBm to measure signal strength')
|
language['display_type_dialog'] = _('Use dBm to measure signal strength')
|
||||||
language['scripts'] = _('Scripts')
|
language['scripts'] = _('Scripts')
|
||||||
language['invalid_address'] = _('Invalid address in $A entry.')
|
#language['invalid_address'] = _('Invalid address in $A entry.')
|
||||||
language['global_settings'] = _('Use these settings for all networks sharing this essid')
|
language['global_settings'] = _('Use these settings for all networks sharing this essid')
|
||||||
language['encrypt_info_missing'] = _('Required encryption information is missing.')
|
language['encrypt_info_missing'] = _('Required encryption information is missing.')
|
||||||
language['enable_encryption'] = _('This network requires encryption to be enabled.')
|
language['enable_encryption'] = _('This network requires encryption to be enabled.')
|
||||||
@@ -610,6 +625,14 @@ def get_language_list_gui():
|
|||||||
language['wicd_curses'] = _("Wicd Curses Interface")
|
language['wicd_curses'] = _("Wicd Curses Interface")
|
||||||
language['dbus_fail'] = _("DBus failure! This is most likely caused by the wicd daemon stopping while wicd-curses is running. Please restart the daemon, and then restart wicd-curses.")
|
language['dbus_fail'] = _("DBus failure! This is most likely caused by the wicd daemon stopping while wicd-curses is running. Please restart the daemon, and then restart wicd-curses.")
|
||||||
|
|
||||||
|
# Fix strings in wicd-curses
|
||||||
|
for i in language.keys():
|
||||||
|
try :
|
||||||
|
language[i] = language[i].decode('utf8')
|
||||||
|
except:
|
||||||
|
print "\"%s\"" % language[i]
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
return language
|
return language
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ daemon = dbus_dict["daemon"]
|
|||||||
wired = dbus_dict["wired"]
|
wired = dbus_dict["wired"]
|
||||||
wireless = dbus_dict["wireless"]
|
wireless = dbus_dict["wireless"]
|
||||||
|
|
||||||
monitor = to_time = update_callback = None
|
monitor = to_time = update_callback = mainloop = None
|
||||||
|
|
||||||
def diewithdbus(func):
|
def diewithdbus(func):
|
||||||
def wrapper(self, *__args, **__kargs):
|
def wrapper(self, *__args, **__kargs):
|
||||||
@@ -54,11 +54,11 @@ def diewithdbus(func):
|
|||||||
self.__lost_dbus_count = 0
|
self.__lost_dbus_count = 0
|
||||||
return ret
|
return ret
|
||||||
except dbusmanager.DBusException, e:
|
except dbusmanager.DBusException, e:
|
||||||
print "Caught exception %e" % str(e)
|
print "Caught exception %s" % str(e)
|
||||||
if not hasattr(self, "__lost_dbus_count"):
|
if not hasattr(self, "__lost_dbus_count"):
|
||||||
self.__lost_dbus_count = 0
|
self.__lost_dbus_count = 0
|
||||||
if self.__lost_dbus_count > 3:
|
if self.__lost_dbus_count > 3:
|
||||||
sys.exit(1)
|
mainloop.quit()
|
||||||
self.__lost_dbus_count += 1
|
self.__lost_dbus_count += 1
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -351,7 +351,7 @@ def main():
|
|||||||
an amount of time determined by the active backend.
|
an amount of time determined by the active backend.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
global monitor, to_time
|
global monitor, to_time, mainloop
|
||||||
|
|
||||||
monitor = ConnectionStatus()
|
monitor = ConnectionStatus()
|
||||||
to_time = daemon.GetBackendUpdateInterval()
|
to_time = daemon.GetBackendUpdateInterval()
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ class Controller(object):
|
|||||||
self.disconnect_script = None
|
self.disconnect_script = None
|
||||||
self.driver = None
|
self.driver = None
|
||||||
self.iface = None
|
self.iface = None
|
||||||
self.backend_manager = BackendManager()
|
self.backend_manager = BackendManager()
|
||||||
|
|
||||||
def get_debug(self): return self._debug
|
def get_debug(self): return self._debug
|
||||||
def set_debug(self, value):
|
def set_debug(self, value):
|
||||||
@@ -226,7 +226,7 @@ class Controller(object):
|
|||||||
self.iface.dhcp_object = None
|
self.iface.dhcp_object = None
|
||||||
|
|
||||||
def IsUp(self):
|
def IsUp(self):
|
||||||
""" Calls the IsUp method for the wired interface.
|
""" Calls the IsUp method for the wired interface.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if the interface is up, False otherwise.
|
True if the interface is up, False otherwise.
|
||||||
@@ -999,3 +999,4 @@ class WiredConnectThread(ConnectThread):
|
|||||||
|
|
||||||
self.connect_result = "Success"
|
self.connect_result = "Success"
|
||||||
self.is_connecting = False
|
self.is_connecting = False
|
||||||
|
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ class TrayIcon(object):
|
|||||||
""" Determines which image to use for the wireless entries. """
|
""" Determines which image to use for the wireless entries. """
|
||||||
def fix_strength(val, default):
|
def fix_strength(val, default):
|
||||||
""" Assigns given strength to a default value if needed. """
|
""" Assigns given strength to a default value if needed. """
|
||||||
return val is not None and int(val) or default
|
return val and int(val) or default
|
||||||
|
|
||||||
def get_prop(prop):
|
def get_prop(prop):
|
||||||
return wireless.GetWirelessProperty(net_id, prop)
|
return wireless.GetWirelessProperty(net_id, prop)
|
||||||
|
|||||||
@@ -34,21 +34,43 @@ class WirelessInterface() -- Control a wireless network interface.
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import random
|
import random
|
||||||
|
import time
|
||||||
from string import maketrans, translate
|
from string import maketrans, translate
|
||||||
|
|
||||||
import wpath
|
import wpath
|
||||||
import misc
|
import misc
|
||||||
from misc import find_path
|
from misc import find_path
|
||||||
|
|
||||||
|
# Regular expressions.
|
||||||
|
__re_mode = (re.I | re.M | re.S)
|
||||||
|
essid_pattern = re.compile('.*ESSID:"?(.*?)"?\s*\n', __re_mode)
|
||||||
|
ap_mac_pattern = re.compile('.*Address: (.*?)\n', __re_mode)
|
||||||
|
channel_pattern = re.compile('.*Channel:? ?(\d\d?)', __re_mode)
|
||||||
|
strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)', __re_mode)
|
||||||
|
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)', __re_mode)
|
||||||
|
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)', __re_mode)
|
||||||
|
mode_pattern = re.compile('.*Mode:(.*?)\n', __re_mode)
|
||||||
|
freq_pattern = re.compile('.*Frequency:(.*?)\n', __re_mode)
|
||||||
|
wep_pattern = re.compile('.*Encryption key:(.*?)\n', __re_mode)
|
||||||
|
altwpa_pattern = re.compile('(wpa_ie)', __re_mode)
|
||||||
|
wpa1_pattern = re.compile('(WPA Version 1)', __re_mode)
|
||||||
|
wpa2_pattern = re.compile('(WPA2)', __re_mode)
|
||||||
|
|
||||||
|
#iwconfig-only regular expressions.
|
||||||
|
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)',re.S)
|
||||||
|
bssid_pattern = re.compile('.*Access Point: (([0-9A-Z]{2}:){5}[0-9A-Z]{2})', __re_mode)
|
||||||
|
|
||||||
|
# Regular expressions for wpa_cli output
|
||||||
|
auth_pattern = re.compile('.*wpa_state=(.*?)\n', __re_mode)
|
||||||
|
|
||||||
RALINK_DRIVER = 'ralink legacy'
|
RALINK_DRIVER = 'ralink legacy'
|
||||||
|
|
||||||
|
|
||||||
blacklist_strict = '!"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ '
|
blacklist_strict = '!"#$%&\'()*+,./:;<=>?@[\\]^`{|}~ '
|
||||||
blacklist_norm = ";`$!*|><&\\"
|
blacklist_norm = ";`$!*|><&\\"
|
||||||
blank_trans = maketrans("", "")
|
blank_trans = maketrans("", "")
|
||||||
|
|
||||||
__all__ = ["SetDNS", "GetDefaultGateway", "GetWiredInterfaces",
|
__all__ = ["SetDNS", "GetDefaultGateway", "GetWiredInterfaces",
|
||||||
"GetWirelessInterfaces", "IsValidWpaSuppDriver", "NeedsExternalCalls"]
|
"GetWirelessInterfaces", "IsValidWpaSuppDriver"]
|
||||||
|
|
||||||
def _sanitize_string(string):
|
def _sanitize_string(string):
|
||||||
if string:
|
if string:
|
||||||
@@ -135,7 +157,6 @@ def NeedsExternalCalls():
|
|||||||
""" Returns True if the backend needs to use an external program. """
|
""" Returns True if the backend needs to use an external program. """
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
def IsValidWpaSuppDriver(driver):
|
def IsValidWpaSuppDriver(driver):
|
||||||
""" Returns True if given string is a valid wpa_supplicant driver. """
|
""" Returns True if given string is a valid wpa_supplicant driver. """
|
||||||
output = misc.Run(["wpa_supplicant", "-D%s" % driver, "-iolan19",
|
output = misc.Run(["wpa_supplicant", "-D%s" % driver, "-iolan19",
|
||||||
@@ -161,6 +182,7 @@ class BaseInterface(object):
|
|||||||
self.DHCP_CLIENT = None
|
self.DHCP_CLIENT = None
|
||||||
self.flush_tool = None
|
self.flush_tool = None
|
||||||
self.link_detect = None
|
self.link_detect = None
|
||||||
|
self.dhcp_object = None
|
||||||
|
|
||||||
def SetDebugMode(self, value):
|
def SetDebugMode(self, value):
|
||||||
""" If True, verbose output is enabled. """
|
""" If True, verbose output is enabled. """
|
||||||
@@ -529,16 +551,46 @@ class BaseInterface(object):
|
|||||||
The IP address of the interface in dotted quad form.
|
The IP address of the interface in dotted quad form.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
if not ifconfig:
|
||||||
|
cmd = 'ifconfig ' + self.iface
|
||||||
|
if self.verbose: print cmd
|
||||||
|
output = misc.Run(cmd)
|
||||||
|
else:
|
||||||
|
output = ifconfig
|
||||||
|
return misc.RunRegex(ip_pattern, output)
|
||||||
|
|
||||||
def IsUp(self):
|
def IsUp(self, ifconfig=None):
|
||||||
""" Determines if the interface is up.
|
""" Determines if the interface is up.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if the interface is up, False otherwise.
|
True if the interface is up, False otherwise.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
if not self.iface: return False
|
||||||
|
flags_file = '/sys/class/net/%s/flags' % self.iface
|
||||||
|
try:
|
||||||
|
flags = open(flags_file, "r").read().strip()
|
||||||
|
except IOError:
|
||||||
|
print "Could not open %s, using ifconfig to determine status" % flags_file
|
||||||
|
return self._slow_is_up(ifconfig)
|
||||||
|
return bool(int(flags, 16) & 1)
|
||||||
|
|
||||||
|
|
||||||
|
def _slow_is_up(self, ifconfig=None):
|
||||||
|
""" Determine if an interface is up using ifconfig. """
|
||||||
|
if not ifconfig:
|
||||||
|
cmd = "ifconfig " + self.iface
|
||||||
|
if self.verbose: print cmd
|
||||||
|
output = misc.Run(cmd)
|
||||||
|
else:
|
||||||
|
output = ifconfig
|
||||||
|
lines = output.split('\n')
|
||||||
|
if len(lines) < 5:
|
||||||
|
return False
|
||||||
|
for line in lines[1:4]:
|
||||||
|
if line.strip().startswith('UP'):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class BaseWiredInterface(BaseInterface):
|
class BaseWiredInterface(BaseInterface):
|
||||||
@@ -555,17 +607,95 @@ class BaseWiredInterface(BaseInterface):
|
|||||||
|
|
||||||
def GetPluggedIn(self):
|
def GetPluggedIn(self):
|
||||||
""" Get the current physical connection state.
|
""" Get the current physical connection state.
|
||||||
|
|
||||||
The method will first attempt to use ethtool do determine
|
The method will first attempt to use ethtool do determine
|
||||||
physical connection state. Should ethtool fail to run properly,
|
physical connection state. Should ethtool fail to run properly,
|
||||||
mii-tool will be used instead.
|
mii-tool will be used instead.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if a link is detected, False otherwise.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not self.iface:
|
||||||
|
return False
|
||||||
|
# check for link using /sys/class/net/iface/carrier
|
||||||
|
# is usually more accurate
|
||||||
|
sys_device = '/sys/class/net/%s/' % self.iface
|
||||||
|
carrier_path = sys_device + 'carrier'
|
||||||
|
if not self.IsUp():
|
||||||
|
MAX_TRIES = 3
|
||||||
|
tries = 0
|
||||||
|
self.Up()
|
||||||
|
while True:
|
||||||
|
tries += 1
|
||||||
|
time.sleep(2)
|
||||||
|
if self.IsUp() or tries > MAX_TRIES: break
|
||||||
|
|
||||||
|
if os.path.exists(carrier_path):
|
||||||
|
carrier = open(carrier_path, 'r')
|
||||||
|
try:
|
||||||
|
link = carrier.read().strip()
|
||||||
|
link = int(link)
|
||||||
|
if link == 1:
|
||||||
|
return True
|
||||||
|
elif link == 0:
|
||||||
|
return False
|
||||||
|
except (IOError, ValueError, TypeError):
|
||||||
|
print 'Error checking link using /sys/class/net/%s/carrier' % self.iface
|
||||||
|
|
||||||
|
if self.ethtool_cmd and self.link_detect in [misc.ETHTOOL, misc.AUTO]:
|
||||||
|
return self._eth_get_plugged_in()
|
||||||
|
elif self.miitool_cmd and self.link_detect in [misc.MIITOOL, misc.AUTO]:
|
||||||
|
return self._mii_get_plugged_in()
|
||||||
|
else:
|
||||||
|
print ('Error: No way of checking for a wired connection. Make ' +
|
||||||
|
'sure that either mii-tool or ethtool is installed.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _eth_get_plugged_in(self):
|
||||||
|
""" Use ethtool to determine the physical connection state.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
True if a link is detected, False otherwise.
|
True if a link is detected, False otherwise.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
cmd = "%s %s" % (self.ethtool_cmd, self.iface)
|
||||||
|
if not self.IsUp():
|
||||||
|
print 'Wired Interface is down, putting it up'
|
||||||
|
self.Up()
|
||||||
|
time.sleep(6)
|
||||||
|
if self.verbose: print cmd
|
||||||
|
tool_data = misc.Run(cmd, include_stderr=True)
|
||||||
|
if misc.RunRegex(re.compile('(Link detected: yes)', re.I | re.M | re.S),
|
||||||
|
tool_data):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _mii_get_plugged_in(self):
|
||||||
|
""" Use mii-tool to determine the physical connection state.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if a link is detected, False otherwise.
|
||||||
|
|
||||||
|
"""
|
||||||
|
cmd = "%s %s" % (self.miitool_cmd, self.iface)
|
||||||
|
if self.verbose: print cmd
|
||||||
|
tool_data = misc.Run(cmd, include_stderr=True)
|
||||||
|
if misc.RunRegex(re.compile('(Invalid argument)', re.I | re.M | re.S),
|
||||||
|
tool_data) is not None:
|
||||||
|
print 'Wired Interface is down, putting it up'
|
||||||
|
self.Up()
|
||||||
|
time.sleep(4)
|
||||||
|
if self.verbose: print cmd
|
||||||
|
tool_data = misc.Run(cmd, include_stderr=True)
|
||||||
|
|
||||||
|
if misc.RunRegex(re.compile('(link ok)', re.I | re.M | re.S),
|
||||||
|
tool_data) is not None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class BaseWirelessInterface(BaseInterface):
|
class BaseWirelessInterface(BaseInterface):
|
||||||
""" Control a wireless network interface. """
|
""" Control a wireless network interface. """
|
||||||
@@ -596,10 +726,6 @@ class BaseWirelessInterface(BaseInterface):
|
|||||||
if self.verbose: print str(cmd)
|
if self.verbose: print str(cmd)
|
||||||
misc.Run(cmd)
|
misc.Run(cmd)
|
||||||
|
|
||||||
def StopWPA(self):
|
|
||||||
""" Stop wireless encryption. """
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def GetKillSwitchStatus(self):
|
def GetKillSwitchStatus(self):
|
||||||
""" Determines if the wireless killswitch is enabled.
|
""" Determines if the wireless killswitch is enabled.
|
||||||
|
|
||||||
@@ -823,10 +949,6 @@ class BaseWirelessInterface(BaseInterface):
|
|||||||
if self.verbose: print cmd
|
if self.verbose: print cmd
|
||||||
misc.Run(cmd)
|
misc.Run(cmd)
|
||||||
|
|
||||||
def ValidateAuthentication(self, auth_time):
|
|
||||||
""" Validate WPA authentication. """
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def _AuthenticateRalinkLegacy(self, network):
|
def _AuthenticateRalinkLegacy(self, network):
|
||||||
""" Authenticate with the specified wireless network.
|
""" Authenticate with the specified wireless network.
|
||||||
|
|
||||||
@@ -866,9 +988,207 @@ class BaseWirelessInterface(BaseInterface):
|
|||||||
if self.verbose: print ' '.join(cmd)
|
if self.verbose: print ' '.join(cmd)
|
||||||
misc.Run(cmd)
|
misc.Run(cmd)
|
||||||
|
|
||||||
|
def GetNetworks(self):
|
||||||
|
""" Get a list of available wireless networks.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A list containing available wireless networks.
|
||||||
|
|
||||||
|
"""
|
||||||
|
cmd = 'iwlist ' + self.iface + ' scan'
|
||||||
|
if self.verbose: print cmd
|
||||||
|
results = misc.Run(cmd)
|
||||||
|
# Split the networks apart, using Cell as our split point
|
||||||
|
# this way we can look at only one network at a time.
|
||||||
|
# The spaces around ' Cell ' are to minimize the chance that someone
|
||||||
|
# has an essid named Cell...
|
||||||
|
networks = results.split( ' Cell ' )
|
||||||
|
|
||||||
|
# Get available network info from iwpriv get_site_survey
|
||||||
|
# if we're using a ralink card (needed to get encryption info)
|
||||||
|
if self.wpa_driver == RALINK_DRIVER:
|
||||||
|
ralink_info = self._GetRalinkInfo()
|
||||||
|
else:
|
||||||
|
ralink_info = None
|
||||||
|
|
||||||
|
# An array for the access points
|
||||||
|
access_points = []
|
||||||
|
for cell in networks:
|
||||||
|
# Only use sections where there is an ESSID.
|
||||||
|
if 'ESSID:' in cell:
|
||||||
|
# Add this network to the list of networks
|
||||||
|
entry = self._ParseAccessPoint(cell, ralink_info)
|
||||||
|
if entry is not None:
|
||||||
|
access_points.append(entry)
|
||||||
|
|
||||||
|
return access_points
|
||||||
|
|
||||||
|
def _ParseAccessPoint(self, cell, ralink_info):
|
||||||
|
""" Parse a single cell from the output of iwlist.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
cell -- string containing the cell information
|
||||||
|
ralink_info -- string contating network information needed
|
||||||
|
for ralink cards.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A dictionary containing the cell networks properties.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
ap = {}
|
||||||
|
ap['essid'] = misc.RunRegex(essid_pattern, cell)
|
||||||
|
try:
|
||||||
|
ap['essid'] = misc.to_unicode(ap['essid'])
|
||||||
|
except (UnicodeDecodeError, UnicodeEncodeError):
|
||||||
|
print 'Unicode problem with current network essid, ignoring!!'
|
||||||
|
return None
|
||||||
|
if ap['essid'] in ['<hidden>', ""]:
|
||||||
|
ap['hidden'] = True
|
||||||
|
ap['essid'] = "<hidden>"
|
||||||
|
else:
|
||||||
|
ap['hidden'] = False
|
||||||
|
|
||||||
|
# Channel - For cards that don't have a channel number,
|
||||||
|
# convert the frequency.
|
||||||
|
ap['channel'] = misc.RunRegex(channel_pattern, cell)
|
||||||
|
if ap['channel'] == None:
|
||||||
|
freq = misc.RunRegex(freq_pattern, cell)
|
||||||
|
ap['channel'] = self._FreqToChannel(freq)
|
||||||
|
|
||||||
|
# BSSID
|
||||||
|
ap['bssid'] = misc.RunRegex(ap_mac_pattern, cell)
|
||||||
|
|
||||||
|
# Mode
|
||||||
|
ap['mode'] = misc.RunRegex(mode_pattern, cell)
|
||||||
|
|
||||||
|
# Break off here if we're using a ralink card
|
||||||
|
if self.wpa_driver == RALINK_DRIVER:
|
||||||
|
ap = self._ParseRalinkAccessPoint(ap, ralink_info, cell)
|
||||||
|
elif misc.RunRegex(wep_pattern, cell) == 'on':
|
||||||
|
# Encryption - Default to WEP
|
||||||
|
ap['encryption'] = True
|
||||||
|
ap['encryption_method'] = 'WEP'
|
||||||
|
|
||||||
|
if misc.RunRegex(wpa1_pattern, cell) == 'WPA Version 1':
|
||||||
|
ap['encryption_method'] = 'WPA'
|
||||||
|
|
||||||
|
if misc.RunRegex(altwpa_pattern, cell) == 'wpa_ie':
|
||||||
|
ap['encryption_method'] = 'WPA'
|
||||||
|
|
||||||
|
if misc.RunRegex(wpa2_pattern, cell) == 'WPA2':
|
||||||
|
ap['encryption_method'] = 'WPA2'
|
||||||
|
else:
|
||||||
|
ap['encryption'] = False
|
||||||
|
|
||||||
|
# Link Quality
|
||||||
|
# Set strength to -1 if the quality is not found
|
||||||
|
|
||||||
|
# more of the patch from
|
||||||
|
# https://bugs.launchpad.net/wicd/+bug/175104
|
||||||
|
if (strength_pattern.match(cell)):
|
||||||
|
[(strength, max_strength)] = strength_pattern.findall(cell)
|
||||||
|
if max_strength:
|
||||||
|
ap["quality"] = 100 * int(strength) // int(max_strength)
|
||||||
|
else:
|
||||||
|
ap["quality"] = int(strength)
|
||||||
|
elif misc.RunRegex(altstrength_pattern,cell):
|
||||||
|
ap['quality'] = misc.RunRegex(altstrength_pattern, cell)
|
||||||
|
else:
|
||||||
|
ap['quality'] = -1
|
||||||
|
|
||||||
|
# Signal Strength (only used if user doesn't want link
|
||||||
|
# quality displayed or it isn't found)
|
||||||
|
if misc.RunRegex(signaldbm_pattern, cell):
|
||||||
|
ap['strength'] = misc.RunRegex(signaldbm_pattern, cell)
|
||||||
|
elif self.wpa_driver != RALINK_DRIVER: # This is already set for ralink
|
||||||
|
ap['strength'] = -1
|
||||||
|
|
||||||
|
return ap
|
||||||
|
|
||||||
|
def ValidateAuthentication(self, auth_time):
|
||||||
|
""" Validate WPA authentication.
|
||||||
|
|
||||||
|
Validate that the wpa_supplicant authentication
|
||||||
|
process was successful.
|
||||||
|
|
||||||
|
NOTE: It's possible this could return False,
|
||||||
|
though in reality wpa_supplicant just isn't
|
||||||
|
finished yet.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
auth_time -- The time at which authentication began.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if wpa_supplicant authenticated succesfully,
|
||||||
|
False otherwise.
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Right now there's no way to do this for these drivers
|
||||||
|
if self.wpa_driver == RALINK_DRIVER or not self.wpa_cli_cmd:
|
||||||
|
return True
|
||||||
|
|
||||||
|
MAX_TIME = 35
|
||||||
|
MAX_DISCONNECTED_TIME = 3
|
||||||
|
disconnected_time = 0
|
||||||
|
while (time.time() - auth_time) < MAX_TIME:
|
||||||
|
cmd = '%s -i %s status' % (self.wpa_cli_cmd, self.iface)
|
||||||
|
output = misc.Run(cmd)
|
||||||
|
result = misc.RunRegex(auth_pattern, output)
|
||||||
|
if self.verbose:
|
||||||
|
print 'WPA_CLI RESULT IS', result
|
||||||
|
|
||||||
|
if not result:
|
||||||
|
return False
|
||||||
|
if result == "COMPLETED":
|
||||||
|
return True
|
||||||
|
elif result == "DISCONNECTED":
|
||||||
|
disconnected_time += 1
|
||||||
|
if disconnected_time > MAX_DISCONNECTED_TIME:
|
||||||
|
disconnected_time = 0
|
||||||
|
# Force a rescan to get wpa_supplicant moving again.
|
||||||
|
self._ForceSupplicantScan()
|
||||||
|
MAX_TIME += 5
|
||||||
|
else:
|
||||||
|
disconnected_time = 0
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print 'wpa_supplicant authentication may have failed.'
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _ForceSupplicantScan(self):
|
||||||
|
""" Force wpa_supplicant to rescan available networks.
|
||||||
|
|
||||||
|
This function forces wpa_supplicant to rescan.
|
||||||
|
This works around authentication validation sometimes failing for
|
||||||
|
wpa_supplicant because it remains in a DISCONNECTED state for
|
||||||
|
quite a while, after which a rescan is required, and then
|
||||||
|
attempting to authenticate. This whole process takes a long
|
||||||
|
time, so we manually speed it up if we see it happening.
|
||||||
|
|
||||||
|
"""
|
||||||
|
print 'wpa_supplicant rescan forced...'
|
||||||
|
cmd = 'wpa_cli -i' + self.iface + ' scan'
|
||||||
|
misc.Run(cmd)
|
||||||
|
|
||||||
|
def StopWPA(self):
|
||||||
|
""" Terminates wpa using wpa_cli"""
|
||||||
|
cmd = 'wpa_cli -i %s terminate' % self.iface
|
||||||
|
if self.verbose: print cmd
|
||||||
|
misc.Run(cmd)
|
||||||
|
|
||||||
def GetBSSID(self, iwconfig=None):
|
def GetBSSID(self, iwconfig=None):
|
||||||
""" Get the MAC address for the interface. """
|
""" Get the MAC address for the interface. """
|
||||||
raise NotImplementedError
|
if not iwconfig:
|
||||||
|
cmd = 'iwconfig ' + self.iface
|
||||||
|
if self.verbose: print cmd
|
||||||
|
output = misc.Run(cmd)
|
||||||
|
else:
|
||||||
|
output = iwconfig
|
||||||
|
|
||||||
|
bssid = misc.RunRegex(bssid_pattern, output)
|
||||||
|
return bssid
|
||||||
|
|
||||||
def GetSignalStrength(self, iwconfig=None):
|
def GetSignalStrength(self, iwconfig=None):
|
||||||
""" Get the signal strength of the current network.
|
""" Get the signal strength of the current network.
|
||||||
@@ -877,7 +1197,28 @@ class BaseWirelessInterface(BaseInterface):
|
|||||||
The signal strength.
|
The signal strength.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
if not iwconfig:
|
||||||
|
cmd = 'iwconfig ' + self.iface
|
||||||
|
if self.verbose: print cmd
|
||||||
|
output = misc.Run(cmd)
|
||||||
|
else:
|
||||||
|
output = iwconfig
|
||||||
|
|
||||||
|
strength_pattern = re.compile('.*Quality:?=? ?(\d+)\s*/?\s*(\d*)',
|
||||||
|
re.I | re.M | re.S)
|
||||||
|
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)', re.I | re.M | re.S)
|
||||||
|
[(strength, max_strength)] = strength_pattern.findall(output)
|
||||||
|
if max_strength and strength:
|
||||||
|
if int(max_strength) != 0:
|
||||||
|
return 100 * int(strength) // int(max_strength)
|
||||||
|
else:
|
||||||
|
# Prevent a divide by zero error.
|
||||||
|
strength = int(strength)
|
||||||
|
|
||||||
|
if strength is None:
|
||||||
|
strength = misc.RunRegex(altstrength_pattern, output)
|
||||||
|
|
||||||
|
return strength
|
||||||
|
|
||||||
def GetDBMStrength(self, iwconfig=None):
|
def GetDBMStrength(self, iwconfig=None):
|
||||||
""" Get the dBm signal strength of the current network.
|
""" Get the dBm signal strength of the current network.
|
||||||
@@ -886,7 +1227,16 @@ class BaseWirelessInterface(BaseInterface):
|
|||||||
The dBm signal strength.
|
The dBm signal strength.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
if not iwconfig:
|
||||||
|
cmd = 'iwconfig ' + self.iface
|
||||||
|
if self.verbose: print cmd
|
||||||
|
output = misc.Run(cmd)
|
||||||
|
else:
|
||||||
|
output = iwconfig
|
||||||
|
signaldbm_pattern = re.compile('.*Signal level:?=? ?(-\d\d*)',
|
||||||
|
re.I | re.M | re.S)
|
||||||
|
dbm_strength = misc.RunRegex(signaldbm_pattern, output)
|
||||||
|
return dbm_strength
|
||||||
|
|
||||||
def GetCurrentNetwork(self, iwconfig=None):
|
def GetCurrentNetwork(self, iwconfig=None):
|
||||||
""" Get the essid of the current network.
|
""" Get the essid of the current network.
|
||||||
@@ -895,4 +1245,14 @@ class BaseWirelessInterface(BaseInterface):
|
|||||||
The current network essid.
|
The current network essid.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
if not iwconfig:
|
||||||
|
cmd = 'iwconfig ' + self.iface
|
||||||
|
if self.verbose: print cmd
|
||||||
|
output = misc.Run(cmd)
|
||||||
|
else:
|
||||||
|
output = iwconfig
|
||||||
|
network = misc.RunRegex(re.compile('.*ESSID:"(.*?)"',
|
||||||
|
re.I | re.M | re.S), output)
|
||||||
|
if network:
|
||||||
|
network = misc.to_unicode(network)
|
||||||
|
return network
|
||||||
|
|||||||
Reference in New Issue
Block a user