From 8112851a86d37e9d26da1fb49bb53eea63460851 Mon Sep 17 00:00:00 2001 From: Dan O'Reilly Date: Sat, 28 Feb 2009 21:52:27 -0500 Subject: [PATCH 1/2] 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), From e699bd5bcb6c4584216afa490d2ab65cc33e15e6 Mon Sep 17 00:00:00 2001 From: Andrew Psaltis Date: Sun, 8 Mar 2009 17:45:38 -0400 Subject: [PATCH 2/2] Fixed wicd-curses to support the new template backend. Made the cacert and clcert fields optional in the eap-tls template. --- curses/netentry_curses.py | 98 ++++++++++++++++++++---------------- curses/wicd-curses.py | 19 ++++--- encryption/templates/eap-tls | 4 +- 3 files changed, 69 insertions(+), 52 deletions(-) diff --git a/curses/netentry_curses.py b/curses/netentry_curses.py index c00c887..fa961bc 100644 --- a/curses/netentry_curses.py +++ b/curses/netentry_curses.py @@ -192,11 +192,12 @@ class AdvancedSettingsDialog(urwid.WidgetWrap): self.overlay.mouse_event( dim, event, button, col, row, focus=True) - 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') + else: + 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: dim = ui.get_cols_rows() @@ -267,7 +268,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'] @@ -298,7 +299,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")) @@ -324,17 +325,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) @@ -343,9 +340,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. """ @@ -356,25 +356,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.overlay,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"): + 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 @@ -385,9 +392,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 @@ -402,26 +409,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/curses/wicd-curses.py b/curses/wicd-curses.py index 0428085..9cfcf98 100644 --- a/curses/wicd-curses.py +++ b/curses/wicd-curses.py @@ -796,13 +796,18 @@ class appGUI(): about_dialog(self.frame) if "C" in keys: focus = self.thePile.get_focus() - if focus == self.wiredCB: - WiredSettingsDialog(self.wiredCB.get_body(). - get_selected_profile()).run(ui,self.size,self.frame) - else: - # wireless list only other option - wid,pos = self.thePile.get_focus().get_focus() - WirelessSettingsDialog(pos).run(ui,self.size,self.frame) + try: + if focus == self.wiredCB: + WiredSettingsDialog(self.wiredCB.get_body(). + get_selected_profile()).run(ui,self.size,self.frame) + else: + # wireless list only other option + wid,pos = self.thePile.get_focus().get_focus() + WirelessSettingsDialog(pos).run(ui,self.size,self.frame) + except: + # wtf do I need this? + loop.quit() + raise #self.netentry = NetEntryBase(dbusmanager.get_dbus_ifaces()) #self.netentry.run(ui,self.size,self.frame) if "I" in keys: 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={