From 8112851a86d37e9d26da1fb49bb53eea63460851 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Sat, 28 Feb 2009 21:52:27 -0500 Subject: [PATCH] Tweak encryption template code so that optional parameters can be supplied. Tweak UI code to reflect that new functionality. Allow for slightly more variation in template formatting. --- encryption/templates/eap | 3 +- encryption/templates/peap-tkip | 5 +- encryption/templates/wep-hex | 2 +- wicd/gui.py | 9 ++- wicd/misc.py | 110 +++++++++++++++++++-------------- wicd/netentry.py | 66 +++++++++++--------- 6 files changed, 114 insertions(+), 81 deletions(-) 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/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 1f23fb8..e3bc14f 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 feafbf7..b06839d 100644 --- a/wicd/misc.py +++ b/wicd/misc.py @@ -262,10 +262,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: @@ -273,49 +269,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 0e1f8fc..27135b6 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),