mirror of
https://github.com/gryf/wicd.git
synced 2025-12-20 12:58:07 +01:00
Fixed typo in the wpa_supplicant string in networking.py. Changed formatting in dapper.py, edgy.py, and networking.py to conform closer to python coding conventions (and hopefully improve readability in general)
924 lines
40 KiB
Python
924 lines
40 KiB
Python
## THE NETWORKING CLASS
|
|
## WRITTEN DECEMBER 18TH, 2006
|
|
## RELEASED UNDER THE GNU General Public License
|
|
|
|
## WRITTEN IN PYTHON, CAN NOT BE USED ALONE
|
|
## MUST BE IMPORTED VIA import networking
|
|
## TO ANOTHER PROJECT IF YOU WISH TO USE IT
|
|
|
|
import os
|
|
import sys
|
|
import wpath
|
|
if __name__ == '__main__':
|
|
wpath.chdir(__file__)
|
|
|
|
# Import the library of random functions that we need here
|
|
# this is also written by me, for this purpose
|
|
import misc
|
|
# Import some other random libraries that we're gonna need.
|
|
import re,threading,thread
|
|
|
|
# Much thanks to wieman01 for help and support with various types of encyption
|
|
# also thanks to foxy123, yopnono, and the many others who reported bugs helped
|
|
# and helped keep this project moving.
|
|
|
|
class Wireless:
|
|
|
|
wireless_interface = None
|
|
wired_interface = None
|
|
wpa_driver = None
|
|
ConnectingThread = None
|
|
before_script = None
|
|
after_script = None
|
|
disconnect_script = None
|
|
|
|
# Create a function to scan for wireless networks
|
|
def Scan(self,essid=None):
|
|
# We ask for an essid, because then we can see hidden networks
|
|
|
|
#####
|
|
## DECLARE THE REGEX PATTERNS
|
|
#####
|
|
|
|
# Init 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:"(.*?)"\n',re.DOTALL | re.I | re.M |
|
|
re.S)
|
|
ap_mac_pattern = re.compile('.*Address: (.*?)\n',re.DOTALL | re.I |
|
|
re.M | re.S)
|
|
channel_pattern = re.compile('.*Channel:? ?(\d\d?)',re.DOTALL | re.I |
|
|
re.M | re.S)
|
|
strength_pattern = re.compile('.*Quality:?=? ?(\d\d*)',re.DOTALL |
|
|
re.I | re.M | re.S)
|
|
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)',
|
|
re.DOTALL | re.I | re.M | re.S)
|
|
mode_pattern = re.compile('.*Mode:(.*?)\n',re.DOTALL | re.I | re.M |
|
|
re.S)
|
|
freq_pattern = re.compile('.*Frequency:(.*?)\n',re.DOTALL | re.I |
|
|
re.M | re.S)
|
|
|
|
wep_pattern = re.compile('.*Encryption key:(.*?)\n',re.DOTALL | re.I |
|
|
re.M | re.S)
|
|
altwpa_pattern = re.compile('(wpa_ie)',re.DOTALL | re.I | re.M | re.S)
|
|
wpa1_pattern = re.compile('(WPA Version 1)',re.DOTALL | re.I | re.M |
|
|
re.S)
|
|
wpa2_pattern = re.compile('(WPA2)',re.DOTALL | re.I | re.M | re.S)
|
|
|
|
#####
|
|
## PREPARE THE INTERFACE
|
|
#####
|
|
|
|
# Prepare the interface for scanning.
|
|
# Note that this must be run as root, otherwise we're gonna have trouble
|
|
misc.Run('ifconfig ' + self.wireless_interface + ' up')
|
|
|
|
essid = misc.Noneify(essid)
|
|
if not essid is None:
|
|
# If there is a hidden essid, we need to tell the computer what it
|
|
# is. Then when it is scanned it will be recognized.
|
|
print "setting hidden essid..." + essid
|
|
misc.Run('iwconfig ' + self.wireless_interface + ' essid "' +
|
|
essid + '"')
|
|
|
|
#####
|
|
## RUN THE SCAN
|
|
#####
|
|
|
|
# Run iwlist scan and get the avaliable networks and
|
|
# save them to scan_data - all in one big string
|
|
scandata = misc.Run('iwlist ' + self.wireless_interface + ' scan')
|
|
|
|
#####
|
|
## PROCESS THE DATA
|
|
#####
|
|
|
|
# Split the networks apart, using Cell as our split point
|
|
# this way we can look at only one network at a time
|
|
networks = scandata.split( ' Cell ' )
|
|
|
|
# Declare
|
|
i=0
|
|
# Make an array for the aps
|
|
aps = {}
|
|
for cell in networks:
|
|
# Search to see if there is an essid in this section
|
|
# if there isn't, that means that it is useless
|
|
# so we don't use it then.
|
|
|
|
# Set essid to the value, this is just a temp variable
|
|
if cell.count("ESSID:") > 0:
|
|
# Since an essid was found
|
|
# we will extract the rest of the info
|
|
# make a dictionary for the data
|
|
CurrentNetwork = {}
|
|
|
|
# Use the RunRegex function to neaten up our code
|
|
# all it does for us is run the regex on the string
|
|
# and return the result,
|
|
# but it makes this code look pretty.
|
|
|
|
CurrentNetwork["essid"] = misc.RunRegex(essid_pattern,cell)
|
|
|
|
if CurrentNetwork["essid"] == "<hidden>":
|
|
CurrentNetwork["hidden"] = True
|
|
# Change the name so it doesn't screw stuff up
|
|
# because it looks like HTML - GTK no like
|
|
CurrentNetwork["essid"] = "Hidden"
|
|
else:
|
|
CurrentNetwork["hidden"] = False
|
|
|
|
CurrentNetwork["channel"] = misc.RunRegex(channel_pattern,cell)
|
|
# Some cards don't show the channel number, so we try
|
|
# assigning the number based on the frequency returned.
|
|
if CurrentNetwork["channel"] is None:
|
|
freq = misc.RunRegex(freq_pattern,cell)
|
|
if freq == '2.412 GHz':
|
|
CurrentNetwork["channel"] = 1
|
|
elif freq == '2.417 GHz':
|
|
CurrentNetwork["channel"] = 2
|
|
elif freq == '2.422 GHz':
|
|
CurrentNetwork["channel"] = 3
|
|
elif freq == '2.427 GHz':
|
|
CurrentNetwork["channel"] = 4
|
|
elif freq == '2.432 GHz':
|
|
CurrentNetwork["channel"] = 5
|
|
elif freq == '2.437 GHz':
|
|
CurrentNetwork["channel"] = 6
|
|
elif freq == '2.442 GHz':
|
|
CurrentNetwork["channel"] = 7
|
|
elif freq == '2.447 GHz':
|
|
CurrentNetwork["channel"] = 8
|
|
elif freq == '2.452 GHz':
|
|
CurrentNetwork["channel"] = 9
|
|
elif freq == '2.457 GHz':
|
|
CurrentNetwork["channel"] = 10
|
|
elif freq == '2.462 GHz':
|
|
CurrentNetwork["channel"] = 11
|
|
elif freq == '2.467 GHz':
|
|
CurrentNetwork["channel"] = 12
|
|
elif freq == '2.472 GHz':
|
|
CurrentNetwork["channel"] = 13
|
|
elif freq == '2.484 GHz':
|
|
CurrentNetwork["channel"] = 14
|
|
else: # Must be a really crappy driver. :(
|
|
print 'Couldn\'t determine channel number for \
|
|
current network'
|
|
|
|
CurrentNetwork["bssid"] = misc.RunRegex(ap_mac_pattern,cell)
|
|
print " ##### " + CurrentNetwork["bssid"]
|
|
CurrentNetwork["mode"] = misc.RunRegex(mode_pattern,cell)
|
|
|
|
# Since encryption needs a True or False,
|
|
# we have to do a simple if then to set it
|
|
if misc.RunRegex(wep_pattern,cell) == "on":
|
|
if self.wpa_driver != 'ralink legacy':
|
|
CurrentNetwork["encryption"] = True
|
|
# Set this, because if it is something else this will
|
|
# be overwritten.
|
|
CurrentNetwork["encryption_method"] = "WEP"
|
|
|
|
if misc.RunRegex(wpa1_pattern,cell) == "WPA Version 1":
|
|
CurrentNetwork["encryption_method"] = "WPA"
|
|
|
|
if misc.RunRegex(altwpa_pattern,cell) == "wpa_ie":
|
|
CurrentNetwork["encryption_method"] = "WPA"
|
|
|
|
if misc.RunRegex(wpa2_pattern,cell) == "WPA2":
|
|
CurrentNetwork["encryption_method"] = "WPA2"
|
|
|
|
# Support for ralink legacy drivers (maybe only
|
|
# serialmonkey enhanced), may not work w/ hidden networks.
|
|
else:
|
|
iwpriv = misc.Run("iwpriv " + self.wireless_interface +
|
|
" get_site_survey")
|
|
lines = iwpriv.splitlines()
|
|
lines = lines[2:]
|
|
for x in lines:
|
|
info = x.split()
|
|
# Make sure we read in a valid entry
|
|
if len(info) < 5 or info is None or info == '':
|
|
break;
|
|
# We've found the network we want to connect to
|
|
if info[2] == CurrentNetwork["essid"]:
|
|
CurrentNetwork["encryption"] = True
|
|
if info[5] == 'WEP' or ((info[5] == 'OPEN' or
|
|
info[5] == 'SHARED') and info[4] == 'WEP'):
|
|
CurrentNetwork["encryption_method"] = 'WEP'
|
|
elif info[5] == 'WPA-PSK':
|
|
CurrentNetwork["encryption_method"] = 'WPA'
|
|
elif info[5] == 'WPA2-PSK':
|
|
CurrentNetwork["encryption_method"] = 'WPA2'
|
|
else:
|
|
print 'Unknown AuthMode, can\'t assign \
|
|
encryption_method!!'
|
|
CurrentNetwork["encryption_method"] = \
|
|
'Unknown'
|
|
# Set signal strength here
|
|
# (not link quality! dBm vs %)
|
|
CurrentNetwork["quality"] = info[1][1:]
|
|
else:
|
|
CurrentNetwork["encryption"] = False
|
|
# End If
|
|
|
|
if self.wpa_driver != 'ralink legacy':
|
|
# Since strength needs a -1 if the quality isn't found
|
|
# we need a simple if then to set it
|
|
if misc.RunRegex(strength_pattern,cell):
|
|
CurrentNetwork["quality"] = misc.RunRegex(
|
|
strength_pattern,cell)
|
|
# Alternate way of labeling link quality
|
|
elif misc.RunRegex(altstrength_pattern,cell):
|
|
CurrentNetwork["quality"] = misc.RunRegex(
|
|
altstrength_pattern,
|
|
cell)
|
|
else:
|
|
CurrentNetwork["quality"] = -1
|
|
|
|
# Add this network to the list of networks
|
|
aps[ i ] = CurrentNetwork
|
|
# Now increment the counter
|
|
i+=1
|
|
# End For
|
|
|
|
# Run a bubble sort to list networks by signal strength
|
|
going = True
|
|
|
|
while going:
|
|
sorted = False
|
|
for i in aps:
|
|
# Set x to the current number
|
|
x = int(i)
|
|
# Set y to the next number
|
|
y = int(i+1)
|
|
|
|
# Only run this if we actually have another element after
|
|
# the current one.
|
|
if (len(aps) > i+1):
|
|
|
|
# Move around depending on qualities.
|
|
# We want the lower qualities at the bottom of the list,
|
|
# so we check to see if the quality below the current one
|
|
# is higher the current one. If it is, we swap them.
|
|
|
|
if (int(aps[int(y)]["quality"]) >
|
|
int(aps[int(x)]["quality"])):
|
|
# Set sorted to true so we don't exit
|
|
sorted=True
|
|
# Do the move
|
|
temp=aps[y]
|
|
aps[y]=aps[x]
|
|
aps[x]=temp
|
|
# End If
|
|
# End If
|
|
# End For
|
|
|
|
if (sorted == False):
|
|
going = False
|
|
# End If
|
|
# End While
|
|
|
|
#return the list of sorted access points
|
|
return aps
|
|
|
|
# End Function Scan
|
|
|
|
def Connect(self,network):
|
|
#call the thread, so we don't hang up the entire works
|
|
self.ConnectingThread = self.ConnectThread(network,
|
|
self.wireless_interface, self.wired_interface,
|
|
self.wpa_driver, self.before_script,
|
|
self.after_script, self.disconnect_script,
|
|
self.global_dns_1, self.global_dns_2,
|
|
self.global_dns_3)
|
|
self.ConnectingThread.start()
|
|
return True
|
|
|
|
class ConnectThread(threading.Thread):
|
|
IsConnecting = None
|
|
ConnectingMessage = None
|
|
ShouldDie = False
|
|
lock = thread.allocate_lock()
|
|
|
|
def __init__(self, network, wireless, wired, wpa_driver, before_script,
|
|
after_script, disconnect_script, gdns1, gdns2, gdns3):
|
|
threading.Thread.__init__(self)
|
|
self.network = network
|
|
self.wireless_interface = wireless
|
|
self.wired_interface = wired
|
|
self.wpa_driver = wpa_driver
|
|
self.IsConnecting = False
|
|
self.before_script = before_script
|
|
self.after_script = after_script
|
|
self.disconnect_script = disconnect_script
|
|
|
|
self.global_dns_1 = gdns1
|
|
self.global_dns_2 = gdns2
|
|
self.global_dns_3 = gdns3
|
|
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'interface_down'
|
|
finally:
|
|
self.lock.release()
|
|
#lock = thread.allocate_lock()
|
|
|
|
def GetStatus(self):
|
|
print "status request"
|
|
print "acqlock",self.lock.acquire()
|
|
try:
|
|
print " ...lock acquired..."
|
|
message = self.ConnectingMessage
|
|
finally:
|
|
self.lock.release()
|
|
print " ...lock released..."
|
|
return message
|
|
|
|
def run(self):
|
|
# Note that we don't put the wired interface down,
|
|
# but we do flush all wired entries from the routing table
|
|
# so it shouldn't be used at all.
|
|
|
|
self.IsConnecting = True
|
|
network = self.network
|
|
|
|
# Execute pre-connection script if necessary.
|
|
if self.before_script != '' and self.before_script != None:
|
|
print 'Executing pre-connection script'
|
|
print misc.Run('./run-script.py ' + self.before_script)
|
|
|
|
# Put it down
|
|
print "interface down..."
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'interface_down'
|
|
finally:
|
|
self.lock.release()
|
|
misc.Run("ifconfig " + self.wireless_interface + " down")
|
|
|
|
# Set a false ip so that when we set the real one, the correct
|
|
# routing entry is created.
|
|
print "Setting false ip..."
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'resetting_ip_address'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
misc.Run("ifconfig " + self.wired_interface + " 0.0.0.0")
|
|
misc.Run("ifconfig " + self.wireless_interface + " 0.0.0.0")
|
|
|
|
print "killing wpa_supplicant, dhclient, dhclient3"
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'removing_old_connection'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
misc.Run("killall dhclient dhclient3 wpa_supplicant")
|
|
|
|
# Check to see if we need to generate a PSK
|
|
if self.wpa_driver != "ralink legacy":
|
|
if not network.get('key') is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'generating_psk'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print "generating psk..."
|
|
key_pattern = re.compile('network={.*?\spsk=(.*?)\n}.*',
|
|
re.DOTALL | re.I | re.M | re.S)
|
|
network["psk"] = misc.RunRegex(key_pattern,
|
|
misc.Run('wpa_passphrase "' +
|
|
network["essid"] + '" "' +
|
|
network["key"] + '"'))
|
|
# Generate the wpa_supplicant file...
|
|
if not network.get('enctype') is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'generating_wpa_config'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print "generating wpa_supplicant configuration file..."
|
|
misc.ParseEncryption(network)
|
|
wpa_string = ("wpa_supplicant -B -i " +
|
|
self.wireless_interface +
|
|
" -c " + wpath.networks + "\"" +
|
|
network["bssid"].replace(":","").lower() +
|
|
"\" -D " + self.wpa_driver)
|
|
print wpa_string
|
|
misc.Run(wpa_string)
|
|
|
|
print "flushing the routing table..."
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'flushing_routing_table'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
misc.Run("ip route flush dev " + self.wireless_interface)
|
|
misc.Run("ip route flush dev " + self.wired_interface)
|
|
|
|
print "configuring the wireless interface..."
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'configuring_interface'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
# Bring it up
|
|
print "interface up..."
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'interface_up'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print misc.Run("ifconfig " + self.wireless_interface + " up")
|
|
|
|
if network["mode"].lower() == "master":
|
|
misc.Run("iwconfig " + self.wireless_interface +
|
|
" mode managed")
|
|
else:
|
|
misc.Run("iwconfig " + self.wireless_interface + " mode " +
|
|
network["mode"])
|
|
|
|
misc.Run("iwconfig " + self.wireless_interface + " essid \"" +
|
|
network["essid"] + "\" channel " + str(network["channel"])
|
|
+ " ap " + network["bssid"])
|
|
|
|
# Adds support for ralink cards that can't use wpasupplicant
|
|
if self.wpa_driver == "ralink legacy":
|
|
if network.get('key') != None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_encryption_info'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print 'setting up ralink encryption'
|
|
iwpriv = misc.Run("iwpriv " + self.wireless_interface +
|
|
" get_site_survey")
|
|
lines = iwpriv.splitlines()
|
|
lines = lines[2:]
|
|
for x in lines:
|
|
info = x.split()
|
|
if len(info) < 5 or info is None or info == '':
|
|
break;
|
|
if info[2] == network.get("essid"):
|
|
if info[5] == 'WEP' or (info[5] == 'OPEN'
|
|
and info[4] == 'WEP'):
|
|
print 'setting up WEP'
|
|
misc.Run("iwconfig " + self.wireless_interface +
|
|
" key " + network.get('key'))
|
|
elif info[5] == 'SHARED' and info[4] == 'WEP':
|
|
print 'setting up WEP'
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set NetworkType=" + info[6])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set AuthMode=SHARED")
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set EncrypType=" + info[4])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set Key1=" + network.get('key'))
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set DefaultKeyID=1")
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set SSID=" + info[2])
|
|
elif info[5] == 'WPA-PSK':
|
|
print 'setting up WPA-PSK'
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set NetworkType=" + info[6])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set AuthMode=WPAPSK")
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set EncrypType=" + info[4])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set SSID=" + info[2])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set WPAPSK=" + network.get('key'))
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set SSID=" + info[2])
|
|
elif info[5] == 'WPA2-PSK':
|
|
print 'setting up WPA2-PSK'
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set NetworkType=" + info[6])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set AuthMode=WPA2PSK")
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set EncrypType=" + info[4])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set SSID=" + info[2])
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set WPAPSK=" + network.get('key'))
|
|
misc.Run("iwpriv " + self.wireless_interface +
|
|
" set SSID=" + info[2])
|
|
else:
|
|
print 'Unknown AuthMode, can\'t complete \
|
|
connection process!!!'
|
|
print "done setting encryption info"
|
|
|
|
if not network.get('broadcast') is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_broadcast_address'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
|
|
print "setting the broadcast address..." + network["broadcast"]
|
|
misc.Run("ifconfig " + self.wireless_interface + " broadcast " +
|
|
network["broadcast"])
|
|
|
|
if not network.get("dns1") is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_static_dns'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print "setting the first dns server...", network["dns1"]
|
|
resolv = open("/etc/resolv.conf","w")
|
|
misc.WriteLine(resolv,"nameserver " + network["dns1"])
|
|
if not network.get("dns2") is None:
|
|
print "setting the second dns server...", network["dns2"]
|
|
misc.WriteLine(resolv,"nameserver " + network["dns2"])
|
|
if not network.get("dns3") is None:
|
|
print "setting the third dns server..."
|
|
misc.WriteLine(resolv,"nameserver " + network["dns3"])
|
|
|
|
if not network.get('ip') is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_static_ip'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print "setting static ips..."
|
|
misc.Run("ifconfig " + self.wireless_interface + " " +
|
|
network["ip"] )
|
|
misc.Run("ifconfig " + self.wireless_interface + " netmask " +
|
|
network["netmask"] )
|
|
print "adding default gateway..." + network["gateway"]
|
|
misc.Run("route add default gw " + network["gateway"])
|
|
else:
|
|
#run dhcp...
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'running_dhcp'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print "running dhcp..."
|
|
if not self.ShouldDie:
|
|
misc.Run("dhclient " + self.wireless_interface)
|
|
|
|
# Code repetition --- bad.
|
|
# However, I think this is the best way.
|
|
|
|
if (network.get('use_static_dns') == True and
|
|
network.get('use_global_dns') == False):
|
|
# Just using normal dns
|
|
if not network.get("dns1") is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_static_dns'
|
|
finally:
|
|
self.lock.release()
|
|
print "setting the first dns server...", network["dns1"]
|
|
resolv = open("/etc/resolv.conf","w")
|
|
misc.WriteLine(resolv,"nameserver " + network["dns1"])
|
|
if not network.get("dns2") is None:
|
|
print "setting the second dns server...",network["dns2"]
|
|
misc.WriteLine(resolv,"nameserver " + network["dns2"])
|
|
if not network.get("dns3") is None:
|
|
print "setting the third dns server..."
|
|
misc.WriteLine(resolv,"nameserver " + network["dns3"])
|
|
resolv.close()
|
|
|
|
if (network.get('use_static_dns') == True and
|
|
network.get('use_global_dns') == True):
|
|
# Using static dns
|
|
if not self.global_dns_1 is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_static_dns'
|
|
finally:
|
|
self.lock.release()
|
|
print "setting the first dns server...", self.global_dns_1
|
|
resolv = open("/etc/resolv.conf","w")
|
|
misc.WriteLine(resolv,"nameserver " + self.global_dns_1)
|
|
if not misc.Noneify(self.global_dns_2) is None:
|
|
print "setting the second dns server...",\
|
|
self.global_dns_2
|
|
misc.WriteLine(resolv,"nameserver " + self.global_dns_2)
|
|
if not misc.Noneify(self.global_dns_3) is None:
|
|
print "setting the third dns server..."
|
|
misc.WriteLine(resolv,"nameserver " + self.global_dns_3)
|
|
resolv.close()
|
|
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'done'
|
|
finally:
|
|
self.lock.release()
|
|
|
|
print "done"
|
|
self.IsConnecting = False
|
|
|
|
# Execute post-connection script if necessary.
|
|
if self.after_script != '' and self.after_script != None:
|
|
print 'executing post connection script'
|
|
print misc.Run('./run-script.py ' + self.after_script)
|
|
# End function Connect
|
|
# End class Connect
|
|
|
|
def GetSignalStrength(self):
|
|
output = misc.Run("iwconfig " + self.wireless_interface)
|
|
strength_pattern = re.compile('.*Quality:?=? ?(\d+)',re.DOTALL | re.I
|
|
| re.M | re.S)
|
|
altstrength_pattern = re.compile('.*Signal level:?=? ?(\d\d*)',re.DOTALL
|
|
| re.I | re.M | re.S)
|
|
strength = misc.RunRegex(strength_pattern,output)
|
|
if strength is None:
|
|
strength = misc.RunRegex(altstrength_pattern,output)
|
|
return strength
|
|
# End function GetSignalStrength
|
|
|
|
def GetCurrentNetwork(self):
|
|
output = misc.Run("iwconfig " + self.wireless_interface)
|
|
essid_pattern = re.compile('.*ESSID:"(.*?)"',re.DOTALL | re.I | re.M
|
|
| re.S)
|
|
return misc.RunRegex(essid_pattern,output)
|
|
# End function GetCurrentNetwork
|
|
|
|
def GetIP(self):
|
|
output = misc.Run("ifconfig " + self.wireless_interface)
|
|
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)',re.S)
|
|
return misc.RunRegex(ip_pattern,output)
|
|
# End function GetIP
|
|
|
|
def CreateAdHocNetwork(self,essid,channel,ip,enctype,key,encused,ics):
|
|
# Remove wpa_supplicant, as it can cause the connection to revert to
|
|
# previous networks...
|
|
misc.Run("killall dhclient dhclient3 wpa_supplicant")
|
|
misc.Run('ifconfig ' + self.wireless_interface + ' down')
|
|
misc.Run('iwconfig ' + self.wireless_interface + ' mode ad-hoc')
|
|
misc.Run('iwconfig ' + self.wireless_interface + ' channel ' + channel)
|
|
misc.Run('iwconfig ' + self.wireless_interface + ' essid ' + essid)
|
|
# Right now it just assumes you're using WEP
|
|
if encused == True:
|
|
misc.Run('iwconfig ' + self.wireless_interface + ' key ' + key)
|
|
|
|
misc.Run('ifconfig ' + self.wireless_interface + ' up')
|
|
misc.Run('ifconfig ' + self.wireless_interface + ' inet ' + ip)
|
|
|
|
# Also just assume that the netmask is 255.255.255.0, it simplifies ICS.
|
|
misc.Run('ifconfig ' + self.wireless_interface +
|
|
' netmask 255.255.255.0')
|
|
|
|
ip_parts = misc.IsValidIP(ip)
|
|
|
|
if ics and ip_parts:
|
|
# Set up internet connection sharing here
|
|
# flush the forward tables
|
|
misc.Run('iptables -F FORWARD')
|
|
misc.Run('iptables -N fw-interfaces')
|
|
misc.Run('iptables -N fw-open')
|
|
misc.Run('iptables -F fw-interfaces')
|
|
misc.Run('iptables -F fw-open')
|
|
misc.Run('iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
|
|
-j TCPMSS --clamp-mss-to-pmtu')
|
|
misc.Run('iptables -A FORWARD -m state --state RELATED,ESTABLISHED \
|
|
-j ACCEPT')
|
|
misc.Run('iptables -A FORWARD -j fw-interfaces ')
|
|
misc.Run('iptables -A FORWARD -j fw-open ')
|
|
misc.Run('iptables -A FORWARD -j REJECT --reject-with \
|
|
icmp-host-unreachable')
|
|
misc.Run('iptables -P FORWARD DROP')
|
|
misc.Run('iptables -A fw-interfaces -i ' + self.wireless_interface +
|
|
' -j ACCEPT')
|
|
basic_ip = '.'.join(ip_parts[0:3]) + '.0' # Not sure that basic_ip is a good name
|
|
misc.Run('iptables -t nat -A POSTROUTING -s ' + basic_ip +
|
|
'/255.255.255.0 -o ' + self.wired_interface +
|
|
' -j MASQUERADE')
|
|
misc.Run('echo 1 > /proc/sys/net/ipv4/ip_forward') # Enable routing
|
|
# End function CreateAdHocNetwork
|
|
|
|
def DetectWirelessInterface(self):
|
|
return misc.RunRegex(re.compile('(\w*)\s*\w*\s*[a-zA-Z0-9.-_]*\s*(?=ESSID)',
|
|
re.DOTALL | re.I | re.M | re.S),
|
|
misc.Run("iwconfig"))
|
|
|
|
def Disconnect(self):
|
|
if self.disconnect_script != None:
|
|
print 'running wireless network disconnect script'
|
|
misc.Run(self.disconnect_script)
|
|
misc.Run('ifconfig ' + self.wireless_interface + ' 0.0.0.0')
|
|
misc.Run('ifconfig ' + self.wireless_interface + ' down')
|
|
|
|
|
|
# End class Wireless
|
|
|
|
class Wired:
|
|
|
|
wireless_interface = None
|
|
wired_interface = None
|
|
ConnectingThread = None
|
|
before_script = None
|
|
after_script = None
|
|
disconnect_script = None
|
|
|
|
def GetIP(self):
|
|
output = misc.Run("ifconfig " + self.wired_interface)
|
|
ip_pattern = re.compile(r'inet [Aa]d?dr[^.]*:([^.]*\.[^.]*\.[^.]*\.[0-9]*)',re.S)
|
|
return misc.RunRegex(ip_pattern,output)
|
|
|
|
def CheckPluggedIn(self):
|
|
mii_tool_data = misc.Run( 'mii-tool ' + self.wired_interface,True)
|
|
if not misc.RunRegex(re.compile('(Invalid argument)',re.DOTALL | re.I |
|
|
re.M | re.S),mii_tool_data) is None:
|
|
print 'wired interface appears down, putting up for mii-tool check'
|
|
misc.Run( 'ifconfig ' + self.wired_interface + ' up' )
|
|
mii_tool_data = misc.Run( 'mii-tool ' + self.wired_interface)
|
|
if not misc.RunRegex(re.compile('(link ok)',re.DOTALL | re.I | re.M |
|
|
re.S),mii_tool_data) is None:
|
|
return True
|
|
else:
|
|
return False
|
|
# End function CheckPluggedIn
|
|
|
|
def Connect(self,network):
|
|
# Call the thread, so we don't hang up the entire works
|
|
self.ConnectingThread = self.ConnectThread(network,
|
|
self.wireless_interface,
|
|
self.wired_interface,
|
|
self.before_script,
|
|
self.after_script,
|
|
self.disconnect_script)
|
|
self.ConnectingThread.start()
|
|
return True
|
|
# End function Connect
|
|
|
|
class ConnectThread(threading.Thread):
|
|
# Wired interface connect thread
|
|
lock = thread.allocate_lock()
|
|
ConnectingMessage = None
|
|
ShouldDie = False
|
|
|
|
def __init__(self,network,wireless,wired,before_script,after_script,
|
|
disconnect_script):
|
|
threading.Thread.__init__(self)
|
|
self.network = network
|
|
self.wireless_interface = wireless
|
|
self.wired_interface = wired
|
|
self.IsConnecting = False
|
|
self.before_script = before_script
|
|
self.after_script = after_script
|
|
self.disconnect_script = disconnect_script
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'interface_down'
|
|
finally:
|
|
self.lock.release()
|
|
# End function __init__
|
|
|
|
def GetStatus(self):
|
|
self.lock.acquire()
|
|
try:
|
|
print " ...lock acquired..."
|
|
message = self.ConnectingMessage
|
|
finally:
|
|
self.lock.release()
|
|
print " ...lock released..."
|
|
return message
|
|
|
|
def run(self):
|
|
# We don't touch the wifi interface
|
|
# but we do remove all wifi entries from the
|
|
# routing table.
|
|
self.IsConnecting = True
|
|
network = self.network
|
|
|
|
if self.before_script != '' and self.before_script != None:
|
|
print 'executing pre-connection script'
|
|
misc.Run('./run-script.py ' + self.before_script)
|
|
|
|
# Put it down
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'interface_down'
|
|
finally:
|
|
self.lock.release()
|
|
print "interface down...", self.wired_interface
|
|
misc.Run("ifconfig " + self.wired_interface + " down")
|
|
|
|
# Set a false ip so that when we set the real one, the correct
|
|
# routing entry is created
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'resetting_ip_address'
|
|
finally:
|
|
self.lock.release()
|
|
print "setting false ip... 0.0.0.0 on", self.wired_interface
|
|
misc.Run("ifconfig " + self.wired_interface + " 0.0.0.0")
|
|
misc.Run("ifconfig " + self.wireless_interface + " 0.0.0.0")
|
|
|
|
# Bring it up
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'interface_up'
|
|
finally:
|
|
self.lock.release()
|
|
print "interface up...", self.wired_interface
|
|
misc.Run("ifconfig " + self.wired_interface + " up")
|
|
|
|
print "killing wpa_supplicant, dhclient, dhclient3"
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'removing_old_connection'
|
|
finally:
|
|
self.lock.release()
|
|
misc.Run("killall dhclient dhclient3 wpa_supplicant")
|
|
|
|
print "flushing the routing table..."
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'flushing_routing_table'
|
|
finally:
|
|
self.lock.release()
|
|
misc.Run("ip route flush dev " + self.wireless_interface)
|
|
misc.Run("ip route flush dev " + self.wired_interface)
|
|
|
|
if not network.get("broadcast") is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_broadcast_address'
|
|
finally:
|
|
self.lock.release()
|
|
print "setting the broadcast address..." + network["broadcast"]
|
|
misc.Run("ifconfig " + self.wired_interface + " broadcast " +
|
|
network["broadcast"])
|
|
|
|
if not network.get("dns1") is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_static_dns'
|
|
finally:
|
|
self.lock.release()
|
|
print "setting the first dns server...", network["dns1"]
|
|
resolv = open("/etc/resolv.conf","w")
|
|
misc.WriteLine(resolv,"nameserver " + network["dns1"])
|
|
if not network.get("dns2") is None:
|
|
print "setting the second dns server...", network["dns2"]
|
|
misc.WriteLine(resolv,"nameserver " + network["dns2"])
|
|
if not network.get("dns3") is None:
|
|
print "setting the third dns server..."
|
|
misc.WriteLine(resolv,"nameserver " + network["dns3"])
|
|
|
|
if not network.get("ip") is None:
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'setting_static_ip'
|
|
finally:
|
|
self.lock.release()
|
|
print "setting static ips...", network["ip"]
|
|
misc.Run("ifconfig " + self.wired_interface + " " +
|
|
network["ip"])
|
|
misc.Run("ifconfig " + self.wired_interface + " netmask " +
|
|
network["netmask"])
|
|
print "adding default gateway..." + network["gateway"]
|
|
misc.Run("route add default gw " + network["gateway"])
|
|
else:
|
|
# Run dhcp...
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'running_dhcp'
|
|
finally:
|
|
self.lock.release()
|
|
print "running dhcp..."
|
|
if not self.ShouldDie:
|
|
misc.Run("dhclient " + self.wired_interface)
|
|
|
|
self.lock.acquire()
|
|
try:
|
|
self.ConnectingMessage = 'done'
|
|
finally:
|
|
self.lock.release()
|
|
self.IsConnecting = False
|
|
|
|
if self.after_script != '' and self.after_script != None:
|
|
print 'executing post connection script'
|
|
misc.Run('./run-script.py ' + self.after_script)
|
|
# End function run
|
|
|
|
def Disconnect(self):
|
|
print 'wired disconnect running'
|
|
if self.disconnect_script != None:
|
|
print 'running wired network disconnect script'
|
|
misc.Run(self.disconnect_script)
|
|
misc.Run('ifconfig ' + self.wired_interface + ' 0.0.0.0')
|
|
misc.Run('ifconfig ' + self.wired_interface + ' down')
|