diff --git a/curses/netentry_curses.py b/curses/netentry_curses.py index 97bf0c1..4e6bf29 100644 --- a/curses/netentry_curses.py +++ b/curses/netentry_curses.py @@ -211,7 +211,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): def __init__(self,networkID): global wireless, daemon AdvancedSettingsDialog.__init__(self) - self.networkID = networkID + self.networkid = networkID global_settings_t = language['global_settings'] encryption_t = language['use_encryption'] autoconnect_t = language['automatic_connect'] @@ -242,7 +242,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): def set_values(self): """ Set the various network settings to the right values. """ - networkID = self.networkID + networkID = self.networkid self.ip_edit.set_edit_text(self.format_entry(networkID,"ip")) self.netmask_edit.set_edit_text(self.format_entry(networkID,"netmask")) self.gateway_edit.set_edit_text(self.format_entry(networkID,"gateway")) @@ -268,17 +268,13 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): # Throw the encryption stuff into a list list = [] + activeID = -1 # Set the menu to this item when we are done for x, enc_type in enumerate(self.encrypt_types): - list.append(enc_type[0]) + list.append(enc_type['name']) + if enc_type['type'] == wireless.GetWirelessProperty(networkID, "enctype"): + activeID = x self.encryption_combo.set_list(list) - self.change_encrypt_method() - activeID = -1 # Set the menu to this item when we are done - user_enctype = wireless.GetWirelessProperty(networkID, "enctype") - for x, enc_type in enumerate(self.encrypt_types): - if enc_type[1] == user_enctype: - activeID = x - self.encryption_combo.set_focus(activeID) if activeID != -1: self.encryption_chkbox.set_state(True,do_callback=False) @@ -287,9 +283,12 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): else: self.encryption_combo.set_focus(0) + self.change_encrypt_method() + + def set_net_prop(self, option, value): """ Sets the given option to the given value for this network. """ - wireless.SetWirelessProperty(self.networkID, option, value) + wireless.SetWirelessProperty(self.networkid, option, value) def format_entry(self, networkid, label): """ Helper method for fetching/formatting wireless properties. """ @@ -300,25 +299,32 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): # Check encryption info if self.encryption_chkbox.get_state(): #print "setting encryption info..." - encryption_info = self.encryption_info - encrypt_methods = misc.LoadEncryptionMethods() + encrypt_info = self.encryption_info + encrypt_methods = self.encrypt_types self.set_net_prop("enctype", - encrypt_methods[self.encryption_combo.get_focus()[1] ][1]) - for x in encryption_info: - if encryption_info[x].get_edit_text() == "": - error(self.ui, self.body,language['encrypt_info_missing']) + encrypt_methods[self.encryption_combo.get_focus()[1] ]['type']) + # Make sure all required fields are filled in. + for entry_info in encrypt_info.itervalues(): + if entry_info[0].get_edit_text() == "" \ + and entry_info[1] == 'required': + error(self.ui, self.overlay,"%s (%s)" \ + % (language['encrypt_info_missing'], + entry_info[0].get_captionabel() ) + ) return False - self.set_net_prop(x, noneToString(encryption_info[x]. + + for entry_key, entry_info in encrypt_info.iteritems(): + self.set_net_prop(entry_key, noneToString(entry_info[0]. get_edit_text())) elif not self.encryption_chkbox.get_state() and \ - wireless.GetWirelessProperty(self.networkID, "encryption"): - error(self.ui, self.body, language['enable_encryption']) + wireless.GetWirelessProperty(self.networkid, "encryption"): + # Encrypt checkbox is off, but the network needs it. + error(self.ui, self.overlay, language['enable_encryption']) return False else: - #print 'encryption is ' + str(wireless.GetWirelessProperty(self.networkID, - # "encryption")) - #print "no encryption specified..." self.set_net_prop("enctype", "None") + for entry in encrypt_info.iterkeys(): + self.set_net_prop(entry[0].entry, "") AdvancedSettingsDialog.save_settings(self) # Save the autoconnect setting. This is not where it originally was @@ -329,9 +335,9 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): self.set_net_prop('use_settings_globally', True) else: self.set_net_prop('use_settings_globally', False) - wireless.RemoveGlobalEssidEntry(self.networkID) + wireless.RemoveGlobalEssidEntry(self.networkid) - wireless.SaveWirelessNetworkProfile(self.networkID) + wireless.SaveWirelessNetworkProfile(self.networkid) return True # More or less ripped from netentry.py @@ -346,26 +352,29 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): # If nothing is selected, select the first entry. if ID == -1: - self.encryption_combo.set_active(0) + self.encryption_combo.set_focus(0) ID = 0 - opts = methods[ID][2] theList = [] - for x in opts: - edit = None - if language.has_key(opts[x][0]): - edit = MaskingEdit(('editcp',language[opts[x][0].lower().replace(' ','_')]+': '),mask_mode='no_focus') - else: - edit = MaskingEdit(('editcp',opts[x][0].replace('_',' ')+': '),mask_mode='no_focus') - theList.append(edit) - # Add the data to any array, so that the information - # can be easily accessed by giving the name of the wanted - # data. - self.encryption_info[opts[x][1]] = edit + for type_ in ['required', 'optional']: + fields = methods[ID][type_] + for field in fields: + if language.has_key(field[1]): + edit = MaskingEdit(('editcp',language[field[1].lower().replace(' ','_')]+': ')) + else: + edit = MaskingEdit(('editcp',field[1].replace('_',' ')+': ')) + edit.set_mask_mode('no_focus') + theList.append(edit) + # Add the data to any array, so that the information + # can be easily accessed by giving the name of the wanted + # data. + self.encryption_info[field[0]] = [edit, type_] - edit.set_edit_text(noneToBlankString( - wireless.GetWirelessProperty(self.networkID, opts[x][1]))) + edit.set_edit_text(noneToBlankString( + wireless.GetWirelessProperty(self.networkid, field[0]))) + #FIXME: This causes the entire pile to light up upon use. + # Make this into a listbox? self.pile_encrypt = DynWrap(urwid.Pile(theList),attrs=('editbx','editnfc')) self._w.body.body.insert(self._w.body.body.__len__(),self.pile_encrypt) #self._w.body.body.append(self.pile_encrypt) diff --git a/encryption/templates/eap b/encryption/templates/eap index a8f71b8..c61fafa 100644 --- a/encryption/templates/eap +++ b/encryption/templates/eap @@ -1,7 +1,8 @@ name = EAP-FAST author = Adam Blackburn version = 2 -require username *Username password *Password pac_file *Path_To_PAC_File +require username *Username password *Password +optional pac_file *Path_To_PAC_File ----- ctrl_interface=/var/run/wpa_supplicant network={ diff --git a/encryption/templates/eap-tls b/encryption/templates/eap-tls index 59f1023..ea6e9fe 100644 --- a/encryption/templates/eap-tls +++ b/encryption/templates/eap-tls @@ -1,7 +1,9 @@ name = EAP-TLS author = Dan O'Reilly version = 1 -require identity *Identity ca_cert *Path_to_CA_Cert client_cert *Path_to_Client_Cert private_key *Private_Key private_key_passwd *Private_Key_Password +require identity *Identity private_key *Private_Key private_key_passwd *Private_Key_Password +optional ca_cert *Path_to_CA_Cert client_cert *Path_to_Client_Cert + ----- ctrl_interface=/var/run/wpa_supplicant network={ diff --git a/encryption/templates/peap-tkip b/encryption/templates/peap-tkip index df141ae..94a9812 100644 --- a/encryption/templates/peap-tkip +++ b/encryption/templates/peap-tkip @@ -1,7 +1,8 @@ -name = PEAP with TKIP +name = PEAP with TKIP/MSCHAPV2 author = Fralaltro version = 1 -require identity *Identity password *Password ca_cert *Path_to_CA_Cert +require identity *Identity password *Password +optional ca_cert *Path_to_CA_Cert ----- ctrl_interface=/var/run/wpa_supplicant network={ diff --git a/encryption/templates/wep-hex b/encryption/templates/wep-hex index e7d147f..6d331bc 100644 --- a/encryption/templates/wep-hex +++ b/encryption/templates/wep-hex @@ -1,4 +1,4 @@ -name = WEP (Hex) +name = WEP (Hex [0-9/A-F]) author = Adam Blackburn version = 1 require key *Key diff --git a/wicd/gui.py b/wicd/gui.py index 4be5bfb..6832337 100644 --- a/wicd/gui.py +++ b/wicd/gui.py @@ -632,9 +632,12 @@ class appGui(object): # Make sure no entries are left blank if entry.chkbox_encryption.get_active(): encryption_info = entry.encryption_info - for x in encryption_info: - if encryption_info[x].get_text() == "": - error(self.window, language['encrypt_info_missing']) + for entry_info in encryption_info.itervalues(): + if entry_info[0].entry.get_text() == "" and \ + entry_info[1] == 'required': + error(self, "%s (%s)" % (language['encrypt_info_missing'], + entry_info[0].label.get_label()) + ) return False # Make sure the checkbox is checked when it should be elif not entry.chkbox_encryption.get_active() and \ diff --git a/wicd/misc.py b/wicd/misc.py index 3b7eb00..d5cdb88 100644 --- a/wicd/misc.py +++ b/wicd/misc.py @@ -276,10 +276,6 @@ def LoadEncryptionMethods(): loaded, the template must be listed in the "active" file. """ - def parse_ent(line, key): - return line.replace(key, "").replace("=", "").strip() - - encryptionTypes = [] try: enctypes = open(wpath.encryption + "active","r").readlines() except IOError, e: @@ -287,49 +283,73 @@ def LoadEncryptionMethods(): raise IOError(e) # Parse each encryption method - for x in enctypes: - x = x.strip() - try: - f = open(wpath.encryption + x, "r") - except IOError: - print 'Failed to load encryption type ' + str(x) - continue - line = f.readlines() - f.close() - - cur_type = {} - cur_type[0] = parse_ent(line[0], "name") - cur_type[1] = x - cur_type[2] = {} - - # Find the line containing our required fields. - i = 1 - try: - while not line[i].startswith("require"): - i += 1 - except IndexError: - print "Bad encryption template: Couldn't find 'require' line" - requiredFields = parse_ent(line[i], "require") - requiredFields = requiredFields.split(" ") - - # Get the required fields. - index = -1 - for current in requiredFields: - # The pretty names will start with an * so we can - # separate them with that. - if current[0] == "*": - # Make underscores spaces - # and remove the * - cur_type[2][index][0] = current.replace("_", " ").lstrip("*") - else: - # Add to the list of things that are required. - index = len(cur_type[2]) - cur_type[2][index] = {} - cur_type[2][index][1] = current - # Add the current type to the dict of encryption types. - encryptionTypes.append(cur_type) + encryptionTypes = [] + for enctype in enctypes: + parsed_template = _parse_enc_template(enctype.strip()) + if parsed_template: + encryptionTypes.append(parsed_template) return encryptionTypes +def __parse_field_ent(fields, field_type='require'): + fields = fields.split(" ") + ret = [] + # We need an even number of entries in the line for it to be valid. + if (len(fields) % 2) != 0: + print "Invalid '%s' line found in template %s" % (field_type, enctype) + return None + else: + for val, disp_val in grouper(2, fields, fillvalue=None): + if val.startswith("*") or not disp_val.startswith("*"): + print "Invalid '%s' line found in template %s" % (field_type, enctype) + return None + ret.append([val, disp_val[1:]]) + return ret + +def _parse_enc_template(enctype): + """ Parse an encryption template. """ + def parse_ent(line, key): + return line.replace(key, "").replace("=", "").strip() + + try: + f = open(os.path.join(wpath.encryption, enctype), "r") + except IOError: + print "Failed to open template file %s" % enctype + return None + + cur_type = {} + cur_type["type"] = enctype + cur_type["fields"] = [] + cur_type['optional'] = [] + cur_type['required'] = [] + for index, line in enumerate(f): + if line.startswith("name") and not "name" in cur_type: + cur_type["name"] = parse_ent(line, "name") + elif line.startswith("require"): + cur_type["required"] = __parse_field_ent(parse_ent(line, + "require")) + if not cur_type["required"]: + # An error occured parsing the require line. + continue + elif line.startswith("optional"): + cur_type["optional"] = __parse_field_ent(parse_ent(line, + "optional"), + field_type="optional") + if not cur_type["optional"]: + # An error occured parsing the optional line. + continue + elif line.startswith("----"): + # We're done. + break + f.close() + if not cur_type["required"]: + print "Failed to find a 'require' line in template %s" % enctype + return None + if not cur_type["name"]: + print "Failed to find a 'name' line in template %s" % enctype + return None + else: + return cur_type + def noneToString(text): """ Convert None, "None", or "" to string type "None" diff --git a/wicd/netentry.py b/wicd/netentry.py index 58e0be9..a6e1919 100644 --- a/wicd/netentry.py +++ b/wicd/netentry.py @@ -308,8 +308,8 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): # Build the encryption menu activeID = -1 # Set the menu to this item when we are done for x, enc_type in enumerate(self.encrypt_types): - self.combo_encryption.append_text(enc_type[0]) - if enc_type[1] == wireless.GetWirelessProperty(networkID, "enctype"): + self.combo_encryption.append_text(enc_type['name']) + if enc_type['type'] == wireless.GetWirelessProperty(networkID, "enctype"): activeID = x self.combo_encryption.set_active(activeID) if activeID != -1: @@ -384,7 +384,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): activeID = -1 # Set the menu to this item when we are done user_enctype = wireless.GetWirelessProperty(networkID, "enctype") for x, enc_type in enumerate(self.encrypt_types): - if enc_type[1] == user_enctype: + if enc_type['type'] == user_enctype: activeID = x self.combo_encryption.set_active(activeID) @@ -400,24 +400,32 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): # Check encryption info if self.chkbox_encryption.get_active(): print "setting encryption info..." - encryption_info = self.encryption_info - encrypt_methods = misc.LoadEncryptionMethods() + encrypt_info = self.encryption_info + encrypt_methods = self.encrypt_types self.set_net_prop("enctype", - encrypt_methods[self.combo_encryption.get_active()][1]) - for x in encryption_info: - if encryption_info[x].get_text() == "": - error(self, language['encrypt_info_missing']) + encrypt_methods[self.combo_encryption.get_active()]['type']) + # Make sure all required fields are filled in. + for entry_info in encrypt_info.itervalues(): + if entry_info[0].entry.get_text() == "" and \ + entry_info[1] == 'required': + error(self, "%s (%s)" % (language['encrypt_info_missing'], + entry_info[0].label.get_label()) + ) return False - self.set_net_prop(x, noneToString(encryption_info[x].get_text())) + # Now save all the entries. + for entry_key, entry_info in encrypt_info.iteritems(): + self.set_net_prop(entry_key, + noneToString(entry_info[0].entry.get_text())) elif not self.chkbox_encryption.get_active() and \ wireless.GetWirelessProperty(networkid, "encryption"): + # Encrypt checkbox is off, but the network needs it. error(self, language['enable_encryption']) return False else: print "no encryption specified..." self.set_net_prop("enctype", "None") - for x in self.encryption_info: - self.set_net_prop(x, "") + for entry in encrypt_info.iterkeys(): + self.set_net_prop(entry[0].entry, "") AdvancedSettingsDialog.save_settings(self) if self.chkbox_global_settings.get_active(): @@ -444,7 +452,7 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): for z in self.vbox_encrypt_info: z.destroy() # Remove stuff in there already ID = self.combo_encryption.get_active() - methods = misc.LoadEncryptionMethods() + methods = self.encrypt_types self.encryption_info = {} # If nothing is selected, select the first entry. @@ -452,22 +460,22 @@ class WirelessSettingsDialog(AdvancedSettingsDialog): self.combo_encryption.set_active(0) ID = 0 - opts = methods[ID][2] - for x in opts: - box = None - if language.has_key(opts[x][0]): - box = LabelEntry(language[opts[x][0].lower().replace(' ','_')]) - else: - box = LabelEntry(opts[x][0].replace('_',' ')) - box.set_auto_hidden(True) - self.vbox_encrypt_info.pack_start(box) - # Add the data to any array, so that the information - # can be easily accessed by giving the name of the wanted - # data. - self.encryption_info[opts[x][1]] = box.entry + for type_ in ['required', 'optional']: + fields = methods[ID][type_] + for field in fields: + if language.has_key(field[1]): + box = LabelEntry(language[field[1].lower().replace(' ','_')]) + else: + box = LabelEntry(field[1].replace('_',' ')) + box.set_auto_hidden(True) + self.vbox_encrypt_info.pack_start(box) + # Add the data to a dict, so that the information + # can be easily accessed by giving the name of the wanted + # data. + self.encryption_info[field[0]] = [box, type_] - box.entry.set_text(noneToBlankString( - wireless.GetWirelessProperty(self.networkID, opts[x][1]))) + box.entry.set_text(noneToBlankString( + wireless.GetWirelessProperty(self.networkID, field[0]))) self.vbox_encrypt_info.show_all() @@ -740,7 +748,7 @@ class WirelessNetworkEntry(NetworkEntry): self.set_encryption(wireless.GetWirelessProperty(networkID, 'encryption'), wireless.GetWirelessProperty(networkID, - 'encryption_method')) + 'encryption_method')) self.set_channel(wireless.GetWirelessProperty(networkID, 'channel')) self.name_label.set_use_markup(True) self.name_label.set_label("%s %s %s %s" % (self._escape(self.essid),