home *** CD-ROM | disk | FTP | other *** search
- /**
- * File: modules/CWMTsigKeys.ycp
- * Package: Common widget manipulation, TSIG keys management widget
- * Summary: Routines for management of TSIG keys
- * Authors: Jiri Srain <jsrain@suse.cz>
- *
- * $Id: CWMTsigKeys.ycp 24842 2005-08-12 08:08:03Z visnov $
- *
- */
-
- {
-
- module "CWMTsigKeys";
- textdomain "base";
-
- import "CWM";
- import "Label";
- import "Report";
- import "Popup";
-
- // pre-declarations
-
- global define list<string> AnalyzeTSIGKeyFile (string filename);
-
-
- // private variables
-
- /**
- * Currently configured TSIG keys
- * Each entry is a map with keys "filename" and "key"
- */
- list<map<string,string> > tsig_keys = [];
-
- /**
- * Filenames of the files that contained deleted TSIG keys
- */
- list<string> deleted_tsig_keys = [];
-
- /**
- * Filenames of the new added TSIG keys
- */
- list<string> new_tsig_keys = [];
-
-
- // private functions
-
- /**
- * Redraw the table of DDNS keys
- */
- define void DdnsKeysWidgetRedraw () {
- list items = maplist (map<string,string> k, tsig_keys, {
- return `item (`id (k["key"]:""), k["key"]:"", k["filename"]:"");
- });
- UI::ChangeWidget (`id ("_cwm_delete_key"), `Enabled, size(items) > 0);
- UI::ChangeWidget (`id ("_cwm_key_listing_table"), `Items, items);
- UI::SetFocus (`id ("_cwm_key_listing_table"));
- }
-
- /**
- * Get the file that contains the specified key
- * @param key string key ID
- * @return string file containing the key
- */
- define string Key2File (string key) {
- string filename = "";
- find (map<string,string>k, tsig_keys, {
- if (k["key"]:nil == key)
- {
- filename = k["filename"]:"";
- return true;
- }
- return false;
- });
- y2milestone ("Key: %1, File: %2", key, filename);
- return filename;
- }
-
- /**
- * Remove file with all TSIG keys it contains
- * @param filename string filename of the file with the TSIG keys
- */
- define void RemoveTSIGKeyFile (string filename) {
- new_tsig_keys = filter (string f, new_tsig_keys, {
- return f != filename;
- });
- deleted_tsig_keys = add (deleted_tsig_keys, filename);
- tsig_keys = filter (map<string,string>k, tsig_keys, {
- return k["filename"]:"" != filename;
- });
- }
-
- /**
- * Remove file containing specified TSIG key
- * @param key string key ID
- */
- define void RemoveTSIGKey (string key) {
- string filename = Key2File (key);
- RemoveTSIGKeyFile (filename);
- }
-
- /**
- * Add new file with TSIG key
- * @param filename string filename of the file with the TSIG key
- */
- define void AddTSIGKeyFile (string filename) {
- deleted_tsig_keys = filter (string f, deleted_tsig_keys, {
- return f != filename;
- });
- new_tsig_keys = add (new_tsig_keys, filename);
- list<string> keys = AnalyzeTSIGKeyFile (filename);
- foreach (string k, keys, {
- tsig_keys = add (tsig_keys, $[
- "key" : k,
- "filename" : filename,
- ]);
- });
- }
-
-
- // public routines related to TSIG keys management
-
- /**
- * Remove leading and trailibg blanks and quotes from file name
- * @param filename string file name
- * @return file name without leading/trailing quotes and blanks
- */
- global define string NormalizeFilename (string filename) {
- while (filename != "" && (substring (filename, 0, 1) == " "
- || substring (filename, 0, 1) == "\""))
- {
- filename = substring (filename, 1);
- }
- while (filename != ""
- && (substring (filename, size (filename) - 1, 1) == " "
- || substring (filename, size (filename) - 1, 1) == "\""))
- {
- filename = substring (filename, 0, size (filename) - 1);
- }
- return filename;
- }
-
- /**
- * Analyze file that may contain TSIG keys
- * @param filename string filename of the file that may contain TSIG keys
- * @return a list of all TSIG key IDs in the file
- */
- global define list<string> AnalyzeTSIGKeyFile (string filename) {
- filename = NormalizeFilename (filename);
- string contents = (string)SCR::Read (.target.string, filename);
- if (contents == nil)
- {
- y2warning ("Unable to read file with TSIG keys: %1", filename);
- return [];
- }
- list<string> ret = [];
- list<string> parts = splitstring (contents, "{}");
- foreach (string p, parts, {
- if (regexpmatch (p, ".*key[[:space:]]+[^[:space:]}{;]+\\.* $"))
- {
- ret = add (ret,
- regexpsub (p, ".*key[[:space:]]+([^[:space:]}{;]+)\\.* $", "\\1"));
- }
- });
- y2milestone ("File: %1, Keys: %2", filename, ret);
- return ret;
- }
-
- /**
- * Remove all 3 files holding the TSIG key data
- * @param main string filename of the main file
- */
- global define void DeleteTSIGKeyFromDisk (string main) {
- list<string> keys = AnalyzeTSIGKeyFile (main);
- y2milestone ("Removing file %1, found keys: %2", main, keys);
- foreach (string k, keys, {
- SCR::Execute (.target.bash, sformat (
- "rm -f /etc/named.d/K%1\\.* ",
- tolower (k)));
- });
- SCR::Execute (.target.remove, main);
- }
-
- /**
- * Transformate the list of files to the list of TSIG key description maps
- * @param filenames a list of file names of the TSIG keys
- * @return a list of TSIG key describing maps
- */
- global define list<map<string,string> > Files2KeyMaps (list<string> filenames) {
- list<list<map<string,string> > > tmpret = maplist (string f, filenames, {
- list<string> keys = AnalyzeTSIGKeyFile (f);
- return maplist (string k, keys, {
- return $[
- "filename" : f,
- "key" : k,
- ];
- });
- });
- list<map<string,string> > ret = (list<map<string, string> >)
- flatten (tmpret);
- y2milestone ("Files: %1, Keys: %2", filenames, ret);
- return ret;
- }
-
- /**
- * Get all TSIG keys that present in the files
- * @param filename a list of file names
- * @return a list of all TSIG key IDs
- */
- global define list<string> Files2Keys (list<string> filenames) {
- list<map<string,string> > keys = Files2KeyMaps (filenames);
- list<string> ret = maplist (map<string,string> k, keys, {
- return k["key"]:"";
- });
- y2milestone ("Files: %1, Keys: %2", filenames, ret);
- return ret;
- }
-
-
- // widget related functions
-
- /**
- * Init function of the widget
- * @param map widget a widget description map
- * @param key strnig the widget key
- */
- global define void Init (map<string,any> widget, string key) {
- map<string,any>() get_keys_info = (map<string,any>())
- widget["get_keys_info"]:nil;
- map<string,any> info = get_keys_info ();
- tsig_keys = info["tsig_keys"]:[];
- deleted_tsig_keys = info["removed_files"]:[];
- new_tsig_keys = info["new_files"]:[];
- if (! haskey (info, "tsig_keys"))
- {
- list<string> files = info["key_files"]:[];
- tsig_keys = Files2KeyMaps (files);
- }
- string initial_path = "/etc/named.d/";
- UI::ChangeWidget (`id ("_cwm_existing_key_file"), `Value, initial_path);
- UI::ChangeWidget (`id ("_cwm_new_key_file"), `Value, initial_path);
- UI::ChangeWidget (`id ("_cwm_new_key_id"), `ValidChars,
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
- DdnsKeysWidgetRedraw ();
- }
-
- /**
- * Handle function of the widget
- * @param map widget a widget description map
- * @param key strnig the widget key
- * @param event map event to be handled
- * @return symbol for wizard sequencer or nil
- */
- global define symbol Handle (map<string,any> widget, string key, map event) {
- any ret = event["ID"]:nil;
- string existing_filename = (string)
- UI::QueryWidget (`id ("_cwm_existing_key_file"), `Value);
- string new_filename = (string)
- UI::QueryWidget (`id ("_cwm_new_key_file"), `Value);
- if (ret == "_cwm_delete_key")
- {
- string key = (string)UI::QueryWidget (`id ("_cwm_key_listing_table"),
- `CurrentItem);
- string delete_filename = Key2File (key);
- if (widget["list_used_keys"]:nil != nil
- && is (widget["list_used_keys"]:nil, list<string>()))
- {
- list<string>() lister = (list<string>())
- widget["list_used_keys"]:nil;
- list<string> used_keys = lister ();
- list<string> keys_to_delete = AnalyzeTSIGKeyFile (delete_filename);
- keys_to_delete = filter (string k, keys_to_delete, {
- return contains (used_keys, k);
- });
- if (size (keys_to_delete) > 0)
- {
- string message = mergestring (keys_to_delete, ", ");
- // popup message
- message = _("The selected TSIG key cannot be deleted,
- because it is in use.
- Stop using it in the configuration first.");
- // popup title
- Popup::AnyMessage (_("Cannot delete TSIG key."), message);
- return nil;
- }
- }
- RemoveTSIGKeyFile (delete_filename);
- }
- else if (ret == "_cwm_browse_existing_key_file")
- {
- existing_filename = (string)UI::AskForExistingFile (
- existing_filename,
- "",
- // popup headline
- _("Select File with the Authentication Key"));
- if (existing_filename != nil)
- {
- UI::ChangeWidget (`id ("_cwm_existing_key_file"), `Value,
- existing_filename);
- }
- return nil;
- }
- else if (ret == "_cwm_browse_new_key_file")
- {
- new_filename = (string)UI::AskForSaveFileName (
- new_filename,
- "",
- // popup headline
- _("Select File for the Authentication Key"));
- if (new_filename != nil)
- UI::ChangeWidget (`id ("_cwm_new_key_file"), `Value, new_filename);
- return nil;
- }
- else if (ret == "_cwm_generate_key")
- {
- string key = (string)UI::QueryWidget (`id ("_cwm_new_key_id"), `Value);
- map stat = (map)SCR::Read (.target.stat, new_filename);
- if (size (stat) != 0)
- {
- if (stat["isdir"]:false)
- {
- UI::SetFocus (`id ("new_key_file"));
- Report::Error (
- // error report
- _("Specified filename is an existing directory."));
- return nil;
- }
- // yes-no popup
- if (! Popup::YesNo (_("Specified file exists. Rewrite it?")))
- {
- return nil;
- }
- else
- {
- DeleteTSIGKeyFromDisk (new_filename);
- RemoveTSIGKeyFile (new_filename);
- }
- }
- if (key == nil || key == "")
- {
- UI::SetFocus (`id ("new_key_name"));
- // error report
- Popup::Error (_("The TSIG key ID was not specified."));
- return nil;
- }
- // specified key exists
- if (Key2File (key) != "")
- {
- // yes-no popup
- if (! Popup::YesNo (_("The key with the specified ID exists and is used.
- Remove it?")))
- {
- return nil;
- }
- else
- {
- string remove_file = Key2File (key);
- DeleteTSIGKeyFromDisk (remove_file);
- RemoveTSIGKeyFile (remove_file);
- }
- }
- // specified key is present on the disk, but not used
- if (0 == SCR::Execute (.target.bash, sformat (
- "ls /etc/named.d/K%1\\.*",
- tolower (key))))
- {
- // yes-no popup
- if (Popup::YesNo (_("A key with the specified ID was found
- on your disk. Remove it?")))
- {
- SCR::Execute (.target.bash, sformat (
- "rm -f `ls /etc/named.d/K%1\\.*`",
- tolower (key)));
- list<string> files = (list<string>)SCR::Read (
- .target.dir,
- "/etc/named.d");
- foreach (string f, files, {
- if ( contains (AnalyzeTSIGKeyFile (f), key))
- DeleteTSIGKeyFromDisk (f);
- });
- }
- }
-
- // yes-no popup
- if (! Popup::YesNo (_("The key will be created now. Continue?")))
- return nil;
- SCR::Execute (.target.bash,
- "test -d /etc/named.d || mkdir /etc/named.d");
- string gen_command = sformat (
- "/usr/bin/genDDNSkey --force -f %1 -n %2 -d /etc/named.d",
- new_filename, key);
- y2milestone ("Running %1", gen_command);
- integer gen_ret = (integer)SCR::Execute (.target.bash, gen_command);
- if (gen_ret != 0)
- {
- // error report
- Report::Error (_("Creating the TSIG key failed."));
- return nil;
- }
- ret = "_cwm_add_key";
- existing_filename = new_filename;
- }
- if (ret == "_cwm_add_key")
- {
- map stat = (map)SCR::Read (.target.stat, new_filename);
- if (size (stat) == 0)
- {
- // message popup
- Popup::Message (_("The specified file does not exist."));
- return nil;
- }
- list<string> keys = AnalyzeTSIGKeyFile (existing_filename);
- if (size (keys) == 0)
- {
- // message popup
- Popup::Message (_("The specified file does not contain any TSIG key."));
- return nil;
- }
- list<string> coliding_files = maplist (string k, keys, {
- return Key2File (k);
- });
- coliding_files = filter (string f, toset (coliding_files), {
- return f != "";
- });
- if (size (coliding_files) > 0)
- {
- // yes-no popup
- if (!Popup::YesNo (_("The specified file contains a TSIG key with the same
- identifier as some of already present keys.
- Old keys will be removed. Continue?")))
- {
- return nil;
- }
- else
- {
- foreach (string f, coliding_files, {
- RemoveTSIGKeyFile (f);
- });
- }
- }
- AddTSIGKeyFile (existing_filename);
- }
- DdnsKeysWidgetRedraw ();
- return nil;
- }
-
- /**
- * Store function of the widget
- * @param map widget a widget description map
- * @param key strnig the widget key
- * @param event map that caused widget data storing
- */
- global define void Store (map<string,any> widget, string key, map event) {
- void(map<string,any>) set_info = (void (map<string,any>))
- widget["set_keys_info"]:nil;
- map<string,any> info = $[
- "removed_files" : deleted_tsig_keys,
- "new_files" : new_tsig_keys,
- "tsig_keys" : tsig_keys,
- "key_files" : toset (maplist (map<string,string> k, tsig_keys, {
- return k["filename"]:"";
- })),
- ];
- set_info (info);
- }
-
- /**
- * Store function of the widget
- * @param map widget a widget description map
- * @param key strnig the widget key
- * @param event map that caused widget data storing/**
- * Init function of the widget
- * @param key strnig the widget key
- */
- global define void InitWrapper (string key) {
- Init (CWM::GetProcessedWidget (), key);
- }
-
- /**
- * Handle function of the widget
- * @param map widget a widget description map
- * @param key strnig the widget key
- * @param event map event to be handled
- * @return symbol for wizard sequencer or nil
- */
- global define symbol HandleWrapper (string key, map event) {
- return Handle (CWM::GetProcessedWidget (), key, event);
- }
-
- /**
- * Store function of the widget
- * @param key strnig the widget key
- * @param event map that caused widget data storing
- */
- global define void StoreWrapper (string key, map event) {
- Store (CWM::GetProcessedWidget (), key, event);
- }
-
- /**
- * Get the widget description map
- * @param settings a map of all parameters needed to create the widget properly
- * <pre>
- * "get_keys_info" : map<string,any>() -- function for getting information
- * about TSIG keys. Return map should contain:
- * - "removed_files" : list<string> -- files that have been removed
- * - "new_files" : list<string> -- files that have been added
- * - "tsig_keys" : list<map<string,string>> -- list of all TSIG keys
- * - "key_files" : list<string> -- list of all files that may contain
- * TSIG keys
- * Either "tsig_keys" or "key_files" are mandatory
- * "set_keys_info" : void (map<string,any>) -- function for storing information
- * about keys. Map has keys:
- * - "removed_files" : list<string> -- files that have been removed
- * - "new_files" : list<string> -- files that have been added
- * - "tsig_keys" : list<map<string,string>> -- list of all TSIG keys
- * - "key_files" : list<string> -- list of all files that contain
- * TSIG keys
- *
- * Additional settings:
- * - "list_used_keys" : list<string>() -- function for getting the list of
- * used TSIG keys. The list is used to prevent used TSIG keys from
- * being deleted. If not present, all keys may get deleted.
- * - "help" : string -- help to the whole widget. If not specified, generic help
- * is used (button labels are patched correctly)
- * </pre>
- * @return a map the widget description map
- */
- global define map<string,any> CreateWidget (map<string,any> settings) {
- // tsig keys management dialog help 1/4
- string help = _("<p><big><b>TSIG Key Management</b></big><br>
- Use this dialog to manage the TSIG keys.</p>
- ")
- +
- // tsig keys management dialog help 2/4
- _("<p><big><b>Adding an Existing TSIG Key</b></big><br>
- To add an already created TSIG key, select a <b>Filename</b> of the file
- containing the key and click <b>Add</b>.</p>
- ")
- +
- // tsig keys management dialog help 3/4
- _("<p><big><b>Creating a New TSIG Key</b></big><br>
- To create a new TSIG key, set the <b>Filename</b> of the file in which to
- create the key and the <b>Key ID</b> to identify the key then click
- <b>Generate</b>.</p>
- ")
- +
- // tsig keys management dialog help 4/4
- _("<p><big><b>Removing a TSIG Key</b></big><br>
- To remove a configured TSIG key, select it and click <b>Delete</b>.
- All keys in the same file are deleted.
- If a TSIG key is in use in the configuration
- of the server, it cannot be deleted. The server must stop using it
- in the configuration first.</p>
- ");
-
- term add_existing = `VSquash (
- // Frame label - adding a created server key
- `Frame (_("Add an Existing TSIG Key"),
- `HBox (
- `HWeight (9,
- `HBox (
- `HWeight (7,
- `HBox (
- `TextEntry (`id ("_cwm_existing_key_file"), `opt (`hstretch),
- // text entry
- Label::FileName ())
- )
- ),
- `HWeight (2,
- `HBox (
- `VBox (
- `Label (" "), `PushButton (`id ("_cwm_browse_existing_key_file"),
- Label::BrowseButton ())
- )
- )
- )
- )
- ),
- `HWeight (2,
- `Bottom (
- `VSquash (`PushButton (`id ("_cwm_add_key"), `opt (`hstretch), Label::AddButton ()))
- )
- )
- )
- )
- );
-
- term create_new = `VSquash (
- // Frame label - creating a new server key
- `Frame (_("Create a New TSIG Key"),
- `HBox (
- `HWeight (9,
- `HBox (
- `HWeight (7,
- `HBox (
- // text entry
- `TextEntry (`id ("_cwm_new_key_id"), `opt (`hstretch), _("&Key ID")),
- // text entry
- `TextEntry (`id ("_cwm_new_key_file"), `opt (`hstretch), Label::FileName())
- )
- ),
- `HWeight (2,
- `HBox (
- `VBox (
- `Label (" "),
- `PushButton (`id ("_cwm_browse_new_key_file"), Label::BrowseButton ())
- )
- )
- )
- )
- ),
- `HWeight (2,
- `Bottom (
- // push button
- `VSquash (`PushButton ( `id ("_cwm_generate_key"), `opt(`hstretch), _("&Generate")))
- )
- )
- )
- )
- );
-
- term current_keys = `VBox (
- `VSpacing (0.5),
- // Table header - in fact label
- `Left (`Label (_("Current TSIG Keys"))),
- `HBox (
- `HWeight (9, `Table (`id ("_cwm_key_listing_table"), `header (
- // Table header item - DNS key listing
- _("Key ID"),
- // Table header item - DNS key listing
- _("Filename")
- ), []
- )),
- `HWeight (2, `VBox (
- `VSquash (`PushButton (`id ("_cwm_delete_key"),
- `opt (`hstretch),
- Label::DeleteButton ())),
- `VStretch ()
- ))
- )
- );
-
- term contents = `VBox (
- add_existing,
- create_new,
- current_keys
- );
-
- map<string,any> ret = (map<string,any>)union ($[
- "widget" : `custom,
- "custom_widget" : contents,
- "help" : help,
- "init" : InitWrapper,
- "store" : StoreWrapper,
- "handle" : HandleWrapper,
- ], settings);
-
- return ret;
- }
-
- // EOF
- }
-