home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / boot / i386 / root / usr / share / YaST2 / modules / CWMFirewallInterfaces.ycp < prev    next >
Text File  |  2006-11-29  |  32KB  |  1,049 lines

  1. /**
  2.  * File:    modules/CWMFirewallInterfaces.ycp
  3.  * Package:    Common widget manipulation, firewall interfaces widget
  4.  * Summary:    Routines for selecting interfaces opened in firewall
  5.  * Authors:    Jiri Srain <jsrain@suse.cz>
  6.  *
  7.  * $Id: CWMFirewallInterfaces.ycp 33164 2006-09-27 08:42:24Z jsrain $
  8.  *
  9.  * WARNING: If you want to use this functionality of this module
  10.  *          you should allways call 'SuSEFirewall::Read()' in the
  11.  *          Read() function of you module
  12.  *          and you should call 'SuSEFirewall::Write()' in the
  13.  *          Write() function.
  14.  *
  15.  *        Functionality of this module only changes the SuSEFirewall
  16.  *          settings in memory, it never Reads or Writes the settings.
  17.  *
  18.  *        Additionally you may need to call Progress::set(false)
  19.  *        before SuSEFirewall::Read() or SuSEFirewall::Write().
  20.  */
  21.  
  22. {
  23. module "CWMFirewallInterfaces";
  24. textdomain "base";
  25.  
  26.  
  27.  
  28. import "CWM";
  29. import "Label";
  30. import "Mode";
  31. import "NetworkDevices";
  32. //import "NetworkService";
  33. import "Popup";
  34. import "SuSEFirewall";
  35.  
  36. // used only for (Mode::installation() || Mode::update())
  37. import "SuSEFirewallProposal";
  38.  
  39. // private variables
  40.  
  41. /**
  42.  * List of all interfaces relevant for firewall settings
  43.  */
  44. list<string> all_interfaces = nil;
  45.  
  46. /**
  47.  * List of all items of interfaces to the selection box
  48.  */
  49. list interface_items = nil;
  50.  
  51. /**
  52.  * List of interfaces that are allowed
  53.  */
  54. list<string> allowed_interfaces = nil;
  55.  
  56. /**
  57.  * Information if configuration was changed by user
  58.  */
  59. boolean configuration_changed = nil;
  60.  
  61. /**
  62.  * `Any`-feature is supported in the firewall configuration
  63.  */
  64. boolean any_iface_supported = nil;
  65.  
  66. // private functions
  67.  
  68. /**
  69.  * Enable or disable the firewall details widget according to the status
  70.  * of "open firewall" checkbox
  71.  */
  72. void EnableOrDisableFirewallDetails () {
  73.     if (! UI::WidgetExists (`id ("_cwm_open_firewall")))
  74.     return;
  75.     if (! UI::WidgetExists (`id ("_cwm_firewall_details")))
  76.     return;
  77.     boolean enabled = (boolean)
  78.     UI::QueryWidget (`id ("_cwm_open_firewall"), `Value);
  79.     if (enabled == nil)
  80.     enabled = false;
  81.     if (size (all_interfaces) == 0)
  82.     enabled = false;
  83.  
  84.     //// NetworkManager
  85.     //if (contains(all_interfaces, special_all_nm_interfaces) && enabled) {
  86.     //    allowed_interfaces = add (allowed_interfaces, special_all_nm_interfaces);
  87.     //}
  88.  
  89.     UI::ChangeWidget (`id ("_cwm_firewall_details"), `Enabled, enabled);
  90. }
  91.  
  92. /**
  93.  * Set the firewall status label
  94.  * @param status symbol one of `off, `closed, `open_all, `custom
  95.  */
  96. void SetFirewallLabel (symbol status) {
  97.     string label = "";
  98.     if (status == `off)
  99.     {
  100.     // label
  101.     label = _("Firewall is disabled");
  102.     }
  103.     else if (status == `closed)
  104.     {
  105.     // label
  106.     label = _("Firewall port is closed");
  107.     }
  108.     else if (status == `open_all)
  109.     {
  110.     // label
  111.     label = _("Firewall port is open on all interfaces");
  112.     }
  113.     else if (status == `custom)
  114.     {
  115.     // label
  116.     label = _("Firewall port is open on selected interfaces");
  117.     }
  118.     else if (status == `no_ifaces)
  119.     {
  120.     // label
  121.     label = _("No network interfaces are configured");
  122.     }
  123.     UI::ReplaceWidget (`id (`_cwm_firewall_status_rp),
  124.     `Label (label));
  125. }
  126.  
  127. /**
  128.  * Initialize the list of all known interfaces
  129.  */
  130. void InitAllInterfacesList () {
  131.     // Do not read NetworkDevices when they are already read
  132.     if (! Mode::config () && ! Mode::installation () && ! Mode::update ()) {
  133.     y2milestone("Reading NetworkDevices...");
  134.     NetworkDevices::Read ();
  135.     }
  136.     all_interfaces = NetworkDevices::List ("");
  137.     all_interfaces = filter (string i, all_interfaces, {
  138.     return i != "lo";
  139.     });
  140.     if (! Mode::config ())
  141.     {
  142.     interface_items = maplist (string i, all_interfaces, {
  143.         string label = NetworkDevices::GetValue (i, "BOOTPROTO");
  144.         string ipaddr = NetworkDevices::GetValue (i, "IPADDR");
  145.         if (label == "static" || label == "" || label == nil)
  146.         {
  147.         label = ipaddr;
  148.         }
  149.         else
  150.         {
  151.         label = toupper (label);
  152.         if (ipaddr != nil && ipaddr != "")
  153.             label = sformat ("%1/%2", label, ipaddr);
  154.         }
  155.         if (label == nil || label == "")
  156.         {
  157.         label = i;
  158.         }
  159.         else
  160.         {
  161.         label = sformat ("%1 (%2)", i, label);
  162.         }
  163.         return `item (`id (i), label);
  164.     });
  165.     }
  166.     else
  167.     {
  168.     interface_items = maplist (string i, all_interfaces, {
  169.         return `item (`id (i), i);
  170.     });
  171.     }
  172.  
  173.     any_iface_supported = SuSEFirewall::IsAnyNetworkInterfaceSupported();
  174.  
  175. //    if (NetworkService::IsManaged()) {
  176. //    nm_managed = true;
  177. //    if (all_interfaces == nil) all_interfaces = [];
  178. //    all_interfaces = add (all_interfaces, special_all_nm_interfaces);
  179. //
  180. //    if (interface_items == nil) interface_items = [];
  181. //    interface_items = add (interface_items,
  182. //        // multi selection box item
  183. //        `item (`id (special_all_nm_interfaces), _("All NetworkManager Interfaces"))
  184. //    );
  185. //    
  186. //    // handled by NetworkManager and also any-feature is supported
  187. //    if (any_iface_supported) {
  188. //        nm_ifaces_have_to_be_supported = true;
  189. //    } else {
  190. //        nm_ifaces_have_to_be_supported = false;
  191. //    }
  192. //    } else {
  193. //    nm_managed = false;
  194. //    }
  195. }
  196.  
  197. /**
  198.  * Update the firewall status label according to the current status
  199.  */
  200. void UpdateFirewallStatus () {
  201.     if (all_interfaces == nil)
  202.     InitAllInterfacesList ();
  203.     symbol status = `custom;
  204.  
  205.     if (! SuSEFirewall::GetEnableService())
  206.     status = `off;
  207.     else if (size (all_interfaces) == 0)
  208.     status = `no_ifaces;
  209.     else if (size (all_interfaces) == size (allowed_interfaces))
  210.     status = `open_all;
  211.     else if (size (allowed_interfaces) == 0)
  212.     status = `closed;
  213.  
  214.     y2milestone("Status: %1, All: %2, Allowed: %3", status, all_interfaces, allowed_interfaces);
  215.     SetFirewallLabel (status);
  216.     boolean open = status == `open_all || status == `custom;
  217.     UI::ChangeWidget (`id ("_cwm_open_firewall"), `Value, open);
  218. }
  219.  
  220. /**
  221.  * Get the list of all interfaces that will be selected
  222.  * @param ifaces a list of interfaces selected by the user
  223.  * @params nm_ifaces_have_to_be_selected defines whether also NetworkManager have to be selected too
  224.  * @return a list of interfaces that will be opened
  225.  */
  226. list<string> Selected2Opened (list<string> ifaces, boolean nm_ifaces_have_to_be_selected) {
  227.     y2milestone("Selected ifaces: %1", ifaces);
  228.     list<string> groups = maplist (string i, ifaces, {
  229.     return SuSEFirewall::GetZoneOfInterface (i);
  230.     });
  231.  
  232.     // string 'any' is in the EXT zone
  233.     // all interfaces without zone assigned are covered by this case
  234.     // so, check also the EXT zone
  235.     if (SuSEFirewall::IsAnyNetworkInterfaceSupported()) {
  236.         groups = add (groups, SuSEFirewall::special_all_interface_zone);
  237.     }
  238.  
  239.     groups = toset (groups);
  240.     groups = filter (string g, groups, {
  241.     return g != nil;
  242.     });
  243.     list<list<string> > iface_groups = maplist (string g, groups, {
  244.     list <string> ifaces_also_supported_by_any = SuSEFirewall::GetInterfacesInZoneSupportingAnyFeature (g);
  245.     // If all interfaces in EXT zone are covered by the special 'any' string
  246.     // and none of these interfaces are selected to be open, we can remove all of them
  247.     // disable the service in whole EXT zone
  248.     if (g == SuSEFirewall::special_all_interface_zone) {
  249.         list <string> ifaces_left_explicitely = filter(string iface, ifaces_also_supported_by_any, {
  250.         return contains(ifaces, iface);
  251.         });
  252.         y2milestone("Ifaces left in zone: %1", ifaces_left_explicitely);
  253.         // there are no interfaces left that would be explicitely mentioned in the EXT zone
  254.         if (ifaces_left_explicitely == []) {
  255.         return [];
  256.         // Hmm, some interfaces left
  257.         } else {
  258.         return ifaces_also_supported_by_any;
  259.         }
  260.     // Just report all interfaces mentioned in zone
  261.     } else {
  262.         return ifaces_also_supported_by_any;
  263.     }
  264.     });
  265.     y2milestone("Ifaces touched: %1", iface_groups);
  266.     list<string> new_ifaces = toset (flatten (iface_groups));
  267.     new_ifaces = filter (string i, new_ifaces, {
  268.     return i != nil;
  269.     });
  270.     
  271.     //if (nm_ifaces_have_to_be_selected) {
  272.     //    new_ifaces = toset(add(new_ifaces, special_all_nm_interfaces));
  273.     //}
  274.     
  275.     return toset (new_ifaces);
  276. }
  277.  
  278. /**
  279.  * Display popup with firewall settings details
  280.  */
  281. void DisplayFirewallDetailsPopupHandler (map<string,any> widget) {
  282.  
  283.     void (map<string,any>) common_details_handler = (void(map<string,any>))
  284.     widget["common_details_handler"]:nil;
  285.     if (common_details_handler != nil)
  286.     common_details_handler (widget);
  287. }
  288.  
  289. // public functions
  290.  
  291. // general functions
  292.  
  293. /**
  294.  * Initialize the list of allowed interfaces
  295.  * Changes the internal variables
  296.  * @param services a list of services
  297.  */
  298. global void InitAllowedInterfaces (list<string> services) {
  299.     map<string,boolean> service_status = $[];
  300.  
  301.     map<string,map<string,boolean> > ifaces_info
  302.     = SuSEFirewall::GetServicesInZones (services);
  303.     foreach (string s, map<string,boolean> status, ifaces_info, {
  304.     foreach (string iface, boolean en, status, {
  305.         service_status[iface] = service_status[iface]:true && en;
  306.     });
  307.     });
  308.     service_status = filter (string iface, boolean en, service_status, {
  309.     return en;
  310.     });
  311.     y2milestone("Status: %1", service_status);
  312.     allowed_interfaces = maplist (string iface, boolean en, service_status, {
  313.     return iface;
  314.     });
  315.     
  316.     // Checking whether the string 'any' is in the 'EXT' zone
  317.     // If it is, checking the status of services for this zone
  318.     // If it is enabled, adding it these interfaces into the list of allowed interfaces
  319.     //                   and setting this zone to enabled
  320.     if (SuSEFirewall::IsAnyNetworkInterfaceSupported()) {
  321.     list <string> interfaces_supported_by_any =
  322.         SuSEFirewall::InterfacesSupportedByAnyFeature(SuSEFirewall::special_all_interface_zone);
  323.     if (size(interfaces_supported_by_any)>0) {
  324.         foreach (string service, services, {
  325.         service_status[SuSEFirewall::special_all_interface_zone] =
  326.             SuSEFirewall::IsServiceSupportedInZone(service, SuSEFirewall::special_all_interface_zone)
  327.             && service_status[SuSEFirewall::special_all_interface_zone]:true;
  328.         });
  329.         if (service_status[SuSEFirewall::special_all_interface_zone]:false) {
  330.         allowed_interfaces = (list <string>) union (allowed_interfaces, interfaces_supported_by_any);
  331.         }
  332.     }
  333.     }
  334.  
  335.     //if (contains(all_interfaces, special_all_nm_interfaces)) {
  336.     //    boolean special_all_nm_enabled = size(services) > 0;
  337.     //    foreach (string sr, services, {
  338.     //        if (! SuSEFirewall::IsServiceSupportedInZone (sr, SuSEFirewall::special_all_interface_zone)) {
  339.     //        special_all_nm_enabled = false;
  340.     //        break;
  341.     //        }
  342.     //    });
  343.     //
  344.     //    if (special_all_nm_enabled) allowed_interfaces = toset(add(allowed_interfaces, special_all_nm_interfaces));
  345.     //}
  346.  
  347.     configuration_changed = false;
  348. }
  349.  
  350. /**
  351.  * Store the list of allowed interfaces
  352.  * Users the internal variables
  353.  * @param services a list of services
  354.  */
  355. global void StoreAllowedInterfaces (list<string> services) {
  356.     // do not save anything if configuration didn't change
  357.     if (! configuration_changed)
  358.     return;
  359.     list<string> forbidden_interfaces = filter (string i, all_interfaces, {
  360.     return ! contains (allowed_interfaces, i);
  361.     });
  362.  
  363.     // If configuring firewall in any type of installation
  364.     // proposal must be set to 'modified'
  365.     if (Mode::installation() || Mode::update()) {
  366.     y2milestone("Firewall proposal modified by user");
  367.     SuSEFirewallProposal::SetChangedByUser(true);
  368.     }
  369.  
  370.     //boolean set_nm_enable = false;
  371.     //if (contains(allowed_interfaces, special_all_nm_interfaces)) {
  372.     //    set_nm_enable = true;
  373.     //    // to hide the special interface name
  374.     //    allowed_interfaces = filter(string i, allowed_interfaces, { return i != special_all_nm_interfaces; });
  375.     //}
  376.  
  377.     list <string> interfaces_supported_by_any =
  378.     SuSEFirewall::InterfacesSupportedByAnyFeature(SuSEFirewall::special_all_interface_zone);
  379.  
  380.     if (size (forbidden_interfaces) > 0)
  381.     {
  382.     SuSEFirewall::SetServices (services, forbidden_interfaces, false);
  383.     }
  384.     if (size (allowed_interfaces) > 0)
  385.     {
  386.     SuSEFirewall::SetServices (services, allowed_interfaces, true);
  387.     }
  388.  
  389.     //if (contains(all_interfaces, special_all_nm_interfaces)) {
  390.     //    SuSEFirewall::SetServicesForZones(services, [SuSEFirewall::special_all_interface_zone], set_nm_enable);
  391.     //}
  392. }
  393.  
  394. /**
  395.  * Init function of the widget
  396.  * @param map widget a widget description map
  397.  * @param key strnig the widget key
  398.  */
  399. global define void InterfacesInit (map<string,any> widget, string key) {
  400.     // set the list of ifaces
  401.     if (all_interfaces == nil)
  402.     {
  403.     InitAllInterfacesList ();
  404.     }
  405.     UI::ReplaceWidget (`id ("_cwm_interface_list_rp"),
  406.     `MultiSelectionBox (
  407.         `id ("_cwm_interface_list"),
  408.         // transaltors: selection box title
  409.             _("&Network Interfaces with Open Port in Firewall"),
  410.         interface_items
  411.     )
  412.     );
  413.     // mark open ifaces as open
  414.     UI::ChangeWidget (`id ("_cwm_interface_list"),
  415.     `SelectedItems,
  416.     allowed_interfaces);
  417. }
  418.  
  419. /**
  420.  * Handle function of the widget
  421.  * @param map widget a widget description map
  422.  * @param key strnig the widget key
  423.  * @param event map event to be handled
  424.  * @return symbol for wizard sequencer or nil
  425.  */
  426. global define symbol InterfacesHandle (map<string,any> widget, string key, map event) {
  427.     any event_id = event["ID"]:nil;
  428.     if (event_id == "_cwm_interface_select_all")
  429.     {
  430.     UI::ChangeWidget (`id ("_cwm_interface_list"), `SelectedItems,
  431.         all_interfaces);
  432.     return nil;
  433.     }
  434.     if (event_id == "_cwm_interface_select_none")
  435.     {
  436.     UI::ChangeWidget (`id ("_cwm_interface_list"), `SelectedItems, []);
  437.     return nil;
  438.     }
  439.     //if (contains((list <string>) UI::QueryWidget(`id ("_cwm_interface_list"), `SelectedItems), special_all_nm_interfaces)) {
  440.     //    nm_ifaces_have_to_be_supported = true;
  441.     //} else {
  442.     //    nm_ifaces_have_to_be_supported = false;
  443.     //}
  444.     return nil;
  445. }
  446.  
  447. /**
  448.  * Store function of the widget
  449.  * @param map widget a widget description map
  450.  * @param key strnig the widget key
  451.  * @param event map that caused widget data storing
  452.  */
  453. global define void InterfacesStore (map<string,any> widget, string key, map event) {
  454.     allowed_interfaces = (list<string>)
  455.     UI::QueryWidget (`id ("_cwm_interface_list"), `SelectedItems);
  456.     //allowed_interfaces = Selected2Opened (allowed_interfaces, nm_ifaces_have_to_be_supported);
  457.     allowed_interfaces = Selected2Opened (allowed_interfaces, false);
  458.     configuration_changed = true;
  459. }
  460.  
  461. /**
  462.  * Validate function of the widget
  463.  * @param map widget a widget description map
  464.  * @param key strnig the widget key
  465.  * @param event map event that caused the validation
  466.  * @return true if validation succeeded, false otherwise
  467.  */
  468. global boolean InterfacesValidate (map<string,any> widget, string key, map event) {
  469.     list<string> ifaces = (list<string>)
  470.     UI::QueryWidget (`id ("_cwm_interface_list"), `SelectedItems);
  471.     ifaces = toset (ifaces);
  472.     y2milestone("Selected ifaces: %1", ifaces);
  473.     if (size (ifaces) == 0)
  474.     {
  475.     // question popup
  476.     if (! Popup::YesNo (_("No interface is selected. Service will not
  477. be available for other computers.
  478.  
  479. Continue?")))
  480.     {
  481.         return false;
  482.     }
  483.     }
  484.  
  485.     // NetworkManager interfaces have to be supported
  486.     //if (contains(ifaces, special_all_nm_interfaces)) {
  487.     //    y2milestone("All Network Interfaces were selected.");
  488.     //    if (any_iface_supported) {
  489.     //        y2milestone("any-feature is supported.");
  490.     //    } else {
  491.     //        y2warning("any-feature is NOT supported.");
  492.     //        // yes-no popup
  493.     //        if (! Popup::YesNo ("Because of the SuSE Firewall settings, the port
  494. //for All NetworkManager Interfaces cannot be open.
  495.     //
  496. //Continue?")) return false;
  497.     //    }
  498.     //    
  499.     //    nm_ifaces_have_to_be_supported = true;
  500.     //    ifaces = filter (string i, ifaces, { return i != special_all_nm_interfaces; });
  501.     //} else {
  502.     //    nm_ifaces_have_to_be_supported = false;
  503.     //}
  504.  
  505.     // list<string> firewall_ifaces = toset (Selected2Opened (ifaces, nm_ifaces_have_to_be_supported));
  506.     list<string> firewall_ifaces = toset (Selected2Opened (ifaces, false));
  507.     y2milestone("firewall_ifaces: %1", firewall_ifaces);
  508.  
  509.     list<string> added_ifaces = filter (string i, firewall_ifaces, {
  510.     return ! contains (ifaces, i);
  511.     });
  512.     y2milestone("added_ifaces: %1", added_ifaces);
  513.  
  514.     list<string> removed_ifaces = filter (string i, ifaces, {
  515.     return ! contains (firewall_ifaces, i);
  516.     });
  517.     y2milestone("removed_ifaces: %1", removed_ifaces);
  518.  
  519.     //// to hide that special string
  520.     //added_ifaces = filter (string i, added_ifaces, { return i != special_all_nm_interfaces; });
  521.     if (size (added_ifaces) > 0)
  522.     {
  523.     string ifaces_list = mergestring (added_ifaces, "\n");
  524.     if (! Popup::YesNo (sformat (
  525.         // yes-no popup
  526.         _("Because of SuSE Firewall settings, the port
  527. on the following interfaces will additionally be open:
  528. %1
  529.  
  530. Continue?"),
  531.         ifaces_list)))
  532.     {
  533.         return false;
  534.     }
  535.     }
  536.     //// to hide that special string
  537.     //removed_ifaces = filter (string i, removed_ifaces, { return i != special_all_nm_interfaces; });
  538.     if (size (removed_ifaces) > 0)
  539.     {
  540.     string ifaces_list = mergestring (removed_ifaces, "\n");
  541.     if (! Popup::YesNo (sformat (
  542.         // yes-no popup
  543.         _("Because of SuSE Firewall settings, the port
  544. on the following interfaces cannot be opened:
  545. %1
  546.  
  547. Continue?"),
  548.         ifaces_list)))
  549.     {
  550.         return false;
  551.     }
  552.     }
  553.     return true;
  554. }
  555.  
  556. list <string> buggy_ifaces = [];
  557.  
  558. /**
  559.  * Checks whether it is possible to change the firewall status
  560.  */
  561. boolean CheckPossbilityToChangeFirewall (boolean new_status) {
  562.     // Reset buggy ifaces
  563.     buggy_ifaces = [];
  564.  
  565.     // User want's to disable the service in firewall
  566.     // that works always
  567.     if (new_status == false)
  568.     return true;
  569.  
  570.     // BTW: new_status == true
  571.  
  572.     // 'any' in 'EXT'
  573.     // interfaces are mentioned in some zone or they are covered by the special string
  574.     // enable-on-all or disable-on-all will work
  575.     if (SuSEFirewall::IsAnyNetworkInterfaceSupported())
  576.     return true;
  577.  
  578.     // every network interface must have its zone assigned
  579.     boolean all_ok = true;
  580.     list <map <string, string> > all_ifaces = SuSEFirewall::GetAllKnownInterfaces();
  581.     foreach (map <string, string> one_interface, SuSEFirewall::GetAllKnownInterfaces(), {
  582.     if (one_interface["zone"]:nil == nil || one_interface["zone"]:"" == "") {
  583.         y2warning("Cannot enable service because interface %1 is not mentioned anywhere...", one_interface["id"]:"ID");
  584.         buggy_ifaces = add(buggy_ifaces, one_interface["id"]:"interface");
  585.         all_ok = false;
  586.     }
  587.     });
  588.     if (all_ok) {
  589.     return true;
  590.     } else {
  591.     string ifaces_list = mergestring (buggy_ifaces, "\n");
  592.     // yes-no popup
  593.     if (Popup::YesNo (sformat(_("Because of SuSE Firewall settings, the port
  594. on the following interfaces cannot be opened:
  595. %1
  596.  
  597. Continue?"), ifaces_list))) {
  598.         // all known ifaces are buggy
  599.         if (size(buggy_ifaces) == size(all_ifaces))
  600.         return false;
  601.         else
  602.         // at least one iface isn't buggy
  603.         return true;
  604.     } else {
  605.         // cancel
  606.         buggy_ifaces = all_interfaces;
  607.         return false;
  608.     }
  609.     }
  610.     
  611.     return false;
  612. }
  613.  
  614. /**
  615.  * Init function of the widget
  616.  * @param key strnig the widget key
  617.  */
  618. global define void InterfacesInitWrapper (string key) {
  619.     InterfacesInit (CWM::GetProcessedWidget (), key);
  620. }
  621.  
  622. /**
  623.  * Handle function of the widget
  624.  * @param key strnig the widget key
  625.  * @param event map event to be handled
  626.  * @return symbol for wizard sequencer or nil
  627.  */
  628. global define symbol InterfacesHandleWrapper (string key, map event) {
  629.     return InterfacesHandle (CWM::GetProcessedWidget (), key, event);
  630. }
  631.  
  632. /**
  633.  * Store function of the widget
  634.  * @param key strnig the widget key
  635.  * @param event map that caused widget data storing
  636.  */
  637. global define void InterfacesStoreWrapper (string key, map event) {
  638.     InterfacesStore (CWM::GetProcessedWidget (), key, event);
  639. }
  640.  
  641. /**
  642.  * Validate function of the widget
  643.  * @param key strnig the widget key
  644.  * @param event map event that caused the validation
  645.  * @return true if validation succeeded, false otherwise
  646.  */
  647. global boolean InterfacesValidateWrapper (string key, map event) {
  648.     return InterfacesValidate (CWM::GetProcessedWidget (), key, event);
  649. }
  650.  
  651. /**
  652.  * Get the widget description map
  653.  * @param settings a map of all parameters needed to create the widget properly
  654.  * <pre>
  655.  *
  656.  * Behavior manipulating functions (mandatory)
  657.  * - "get_allowed_interfaces" : list<string>() -- function that returns
  658.  *          the list of allowed network interfaces
  659.  * - "set_allowed_interfaces" : void (list<string>) -- function that sets
  660.  *          the list of allowed interfaces
  661.  *
  662.  * Additional settings:
  663.  * - "help" : string -- help to the whole widget. If not specified, generic help
  664.  *          is used (button labels are patched correctly)
  665.  * </pre>
  666.  * @return map the widget description map
  667.  */
  668. global define map<string,any> CreateInterfacesWidget (map<string,any> settings){
  669.     term widget = `HBox (
  670.     `HSpacing (1),
  671.     `VBox (
  672.         `HSpacing (48),
  673.         `VSpacing (1),
  674.         `ReplacePoint (`id ("_cwm_interface_list_rp"),
  675.         `MultiSelectionBox (
  676.             `id ("_cwm_interface_list"),
  677.             // translators: selection box title
  678.                 _("Network &Interfaces with Open Port in Firewall"),
  679.             []
  680.         )
  681.         ),
  682.         `VSpacing (1),
  683.         `HBox (
  684.         `HStretch (),
  685.         `HWeight (1, `PushButton (`id ("_cwm_interface_select_all"),
  686.             // push button to select all network intefaces for firewall
  687.             _("Select &All"))),
  688.         `HWeight (1, `PushButton (`id ("_cwm_interface_select_none"),
  689.             // push button to deselect all network intefaces for firewall
  690.             _("Select &None"))),
  691.         `HStretch ()
  692.         ),
  693.         `VSpacing (1)
  694.     ),
  695.     `HSpacing (1)
  696.     );
  697.  
  698.     string help = ""; // TODO
  699.  
  700.     if (haskey (settings, "help"))
  701.     {
  702.     help = settings["help"]:"";
  703.     }
  704.  
  705.     map<string,any> ret = (map<string,any>)union (settings, $[
  706.     "widget" : `custom,
  707.     "custom_widget" : widget,
  708.     "help" : help,
  709.     "init" : InterfacesInitWrapper,
  710.     "store" : InterfacesStoreWrapper,
  711.     "handle" : InterfacesHandleWrapper,
  712.     "validate_type" : `function,
  713.     "validate_function" : InterfacesValidateWrapper,
  714.     ]);
  715.  
  716.     return ret;
  717. }
  718.  
  719. /**
  720.  * Display the firewall interfaces selection as a popup
  721.  * @return symbol return value of the dialog
  722.  */
  723. global symbol DisplayDetailsPopup (map<string,any> settings) {
  724. // FIXME breaks help if run in dialog with Tab!!!!!!
  725. // settings stack must be created in CWM::Run
  726.     list<map <string, any> > w = CWM::CreateWidgets (
  727.     ["firewall_ifaces"],
  728.     $[
  729.         "firewall_ifaces" : CreateInterfacesWidget (settings),
  730.     ]
  731.     );
  732.     string help = CWM::MergeHelps (w);
  733.     term contents = `VBox (
  734.     "firewall_ifaces",
  735.     `HBox (
  736.         `HStretch (),
  737.         `PushButton (`id (`ok), Label::OKButton ()),
  738.         `PushButton (`id (`cancel), Label::CancelButton ()),
  739.         `HStretch ()
  740.     )
  741.     );
  742.     contents = CWM::PrepareDialog (contents, w);
  743.     UI::OpenDialog (contents);
  744.     symbol ret = CWM::Run (w, $[]);
  745.     UI::CloseDialog ();
  746.     return ret;
  747. }
  748.  
  749.  
  750. // firewall openning widget
  751.  
  752. /**
  753.  * Initialize the open firewall widget
  754.  * @param widget a map describing the whole widget
  755.  */
  756. global void OpenFirewallInit (map<string,any> widget, string key) {
  757.     if (! UI::WidgetExists (`id ("_cwm_open_firewall")))
  758.     {
  759.     y2error ("Firewall widget doesn't exist");
  760.     return;
  761.     }
  762.     list<string> services = widget["services"]:[];
  763.     InitAllInterfacesList ();
  764.     InitAllowedInterfaces (services);
  765.     boolean open_firewall = size (allowed_interfaces) > 0;
  766.     boolean firewall_enabled = SuSEFirewall::GetEnableService()
  767.     && size (all_interfaces) > 0;
  768.     if (! firewall_enabled)
  769.     {
  770.     open_firewall = false;
  771.     UI::ChangeWidget (`id ("_cwm_open_firewall"), `Enabled, false);
  772.     }
  773.     UI::ChangeWidget (`id ("_cwm_open_firewall"), `Value, open_firewall);
  774.     UpdateFirewallStatus ();
  775.     EnableOrDisableFirewallDetails ();
  776. }
  777.  
  778. /**
  779.  * Store function of the widget
  780.  * @param key strnig the widget key
  781.  * @param event map that caused widget data storing
  782.  */
  783. global void OpenFirewallStore (map<string,any> widget, string key, map event) {
  784.     if (! UI::WidgetExists (`id ("_cwm_open_firewall")))
  785.     {
  786.     y2error ("Widget _cwm_open_firewall does not exist");
  787.     return;
  788.     }
  789.     list<string> services = widget["services"]:[];
  790.     StoreAllowedInterfaces (services);
  791. }
  792.  
  793. /**
  794.  * Handle the immediate start and stop of the service
  795.  * @param widget a map describing the widget
  796.  * @param key strnig the widget key
  797.  * @param event_id any the ID of the occurred event
  798.  * @return always nil
  799.  */
  800. global symbol OpenFirewallHandle (map<string,any> widget, string key, map event) {
  801.     any event_id = event["ID"]:nil;
  802.     if (event_id == "_cwm_firewall_details")
  803.     {
  804.     symbol() handle_firewall_details
  805.         = (symbol())widget["firewall_details_handler"]:nil;
  806.     y2milestone("FD: %1", handle_firewall_details);
  807.     symbol ret = nil;
  808.     y2milestone("RT: %1", ret);
  809.     if (handle_firewall_details != nil)
  810.     {
  811.         ret = handle_firewall_details ();
  812.     }
  813.     else
  814.     {
  815.         map<string,any> w = filter (string k, any v, widget, {
  816.         return "services" == k;
  817.         });
  818.         DisplayDetailsPopup (w);
  819.     }
  820.     UpdateFirewallStatus ();
  821.     EnableOrDisableFirewallDetails ();
  822.     return ret;
  823.     }
  824.     if (event_id == "_cwm_open_firewall")
  825.     {
  826.     boolean value = (boolean)UI::QueryWidget (
  827.         `id ("_cwm_open_firewall"),
  828.         `Value);
  829.     y2milestone("OF: %1", value);
  830.     if (value)
  831.         allowed_interfaces = all_interfaces;
  832.     else
  833.         allowed_interfaces = [];
  834.  
  835.     buggy_ifaces = [];
  836.     // Checks whether it's possible to enable or disable the service for all interfaces
  837.     // opens a popup message when needed
  838.     if (! CheckPossbilityToChangeFirewall(value)) {
  839.         // change the checkbox state back
  840.         UI::ChangeWidget(`id ("_cwm_open_firewall"), `Value, !value);
  841.     }
  842.     // Filtering out buggy ifaces
  843.     foreach (string one_iface, buggy_ifaces, {
  844.         allowed_interfaces = filter(string one_allowed, allowed_interfaces, {
  845.         return one_allowed != one_iface;
  846.         });
  847.     });
  848.  
  849.     UpdateFirewallStatus ();
  850.     EnableOrDisableFirewallDetails ();
  851.     configuration_changed = true;
  852.     }
  853.     return nil;
  854. }
  855.  
  856. /**
  857.  * Init function of the widget
  858.  * @param key strnig the widget key
  859.  */
  860. global void OpenFirewallInitWrapper (string key) {
  861.     OpenFirewallInit (CWM::GetProcessedWidget (), key);
  862. }
  863.  
  864. /**
  865.  * Store function of the widget
  866.  * @param key strnig the widget key
  867.  * @param event map that caused widget data storing
  868.  */
  869. global void OpenFirewallStoreWrapper (string key, map event) {
  870.     OpenFirewallStore (CWM::GetProcessedWidget (), key, event);
  871. }
  872.  
  873. /**
  874.  * Handle the immediate start and stop of the service
  875.  * @param key strnig the widget key
  876.  * @param event_id any the ID of the occurred event
  877.  * @return always nil
  878.  */
  879. global symbol OpenFirewallHandleWrapper (string key, map event) {
  880.     return OpenFirewallHandle (CWM::GetProcessedWidget (), key, event);
  881. }
  882.  
  883. /**
  884.  * Check if the widget was modified
  885.  * @param key strnig the widget key
  886.  * @return boolean true if widget was modified
  887.  */
  888. global boolean OpenFirewallModified (string key) {
  889.     return configuration_changed;
  890. }
  891.  
  892. /**
  893.  * Enable the whole firewal widget
  894.  * @param key strnig the widget key
  895.  */
  896. global void EnableOpenFirewallWidget () {
  897.     if (! UI::WidgetExists (`id ("_cwm_open_firewall")))
  898.     return;
  899.     if (! UI::WidgetExists (`id ("_cwm_firewall_details")))
  900.     return;
  901.     UI::ChangeWidget (`id ("_cwm_open_firewall"), `Enabled, true);
  902.     EnableOrDisableFirewallDetails ();
  903. }
  904.  
  905. /**
  906.  * Disable the whole firewal widget
  907.  * @param key strnig the widget key
  908.  */
  909. global void DisableOpenFirewallWidget () {
  910.     if (! UI::WidgetExists (`id ("_cwm_open_firewall")))
  911.     return;
  912.     if (! UI::WidgetExists (`id ("_cwm_firewall_details")))
  913.     return;
  914.     UI::ChangeWidget (`id ("_cwm_open_firewall"), `Enabled, false);
  915.     UI::ChangeWidget (`id ("_cwm_firewall_details"), `Enabled, false);
  916. }
  917.  
  918. /**
  919.  * Get the template for the help text to the firewall opening widget
  920.  * @param restart_displayed shold be true if "Save and restart" is displayed
  921.  * @return string help text template with %1 and %2 placeholders
  922.  */
  923. global string OpenFirewallHelpTemplate (boolean restart_displayed) {
  924.     // help text for firewall settings widget 1/3,
  925.     // %1 is check box label, eg. "Open Port in Firewall" (without quotes)
  926.     string help = _("<p><b><big>Firewall Settings</big></b><br>
  927. To open the firewall to allow access to the service from remote computers,
  928. set <b>%1</b>.<br>");
  929.     if (restart_displayed)
  930.     {
  931.     // help text for firewall port openning widget 2/3, optional
  932.     // %1 is push button label, eg. "Firewall &Details" (without quotes)
  933.     // note: %2 is correct, do not replace with %1!!!
  934.     help = help + _("To select interfaces on which to open the port,
  935. click <b>%2</b>.<br>");
  936.     }
  937.     // help text for firewall settings widget 3/3,
  938.     help = help + _("This option is available only if the firewall
  939. is enabled.</p>");
  940.     return help;
  941. }
  942.  
  943. /**
  944.  * Get the help text to the firewall opening widget
  945.  * @param restart_displayed shold be true if "Save and restart" is displayed
  946.  * @return string help text
  947.  */
  948. global string OpenFirewallHelp (boolean restart_displayed) {
  949.     return sformat (OpenFirewallHelpTemplate (restart_displayed),
  950.     // part of help text - check box label, NO SHORTCUT!!!
  951.     _("Open Port in Firewall"),
  952.     // part of help text - push button label, NO SHORTCUT!!!
  953.     _("Firewall Details"));
  954. }
  955.  
  956. /**
  957.  * Get the widget description map of the firewall enablement widget
  958.  * @param settings a map of all parameters needed to create the widget properly
  959.  * <pre>
  960.  *
  961.  * - "services" : list<string> -- services identifications for the Firewall.ycp
  962.  *          module
  963.  * - "display_details" : boolean -- true if the details button should be
  964.  *          displayed
  965.  * - "firewall_details_handler" : symbol () -- function to handle the firewall
  966.  *          details button. If returns something else than nil, dialog is
  967.  *          exited with the returned symbol as value for wizard sequencer.
  968.  *          If not specified, but "display_details" is true, common popup
  969.  *          is used.
  970.  * - "open_firewall_checkbox" : string -- label of the check box
  971.  * - "firewall_details_button" : string -- label of the push button for
  972.  *          changing firewall details
  973.  * - "help" : string -- help to the widget. If not specified, generic help
  974.  *          is used
  975.  * </pre>
  976.  * @return map the widget description map
  977.  */
  978. global map<string,any> CreateOpenFirewallWidget (map<string,any> settings) {
  979.     string help = "";
  980.     string open_firewall_checkbox
  981.     // check box
  982.     = settings["open_firewall_checkbox"]:_("Open Port in &Firewall");
  983.     string firewall_details_button
  984.     // push button
  985.     = settings["firewall_details_button"]:_("Firewall &Details");
  986.     boolean display_firewall_details
  987.     = haskey (settings, "firewall_details_handler")
  988.         || settings["display_details"]:false;
  989.     if (haskey (settings, "help"))
  990.     {
  991.     help = settings["help"]:"";
  992.     }
  993.     else
  994.     {
  995.     help = OpenFirewallHelp (display_firewall_details);
  996.     }
  997.  
  998.     term firewall_settings = `CheckBox (`id ("_cwm_open_firewall"),
  999.     `opt (`notify),
  1000.     open_firewall_checkbox);
  1001.     if (display_firewall_details)
  1002.     {
  1003.     firewall_settings = `HBox (
  1004.         firewall_settings,
  1005.         `HSpacing (2),
  1006.         `PushButton (`id ("_cwm_firewall_details"),
  1007.         firewall_details_button)
  1008.     );
  1009.     }
  1010.     firewall_settings = `VBox (
  1011.     `Left (firewall_settings),
  1012.     `Left (`ReplacePoint (`id (`_cwm_firewall_status_rp),
  1013.         // label text
  1014.         `Label (_("Firewall is open")))
  1015.     )
  1016.     );
  1017.  
  1018.     if (! haskey (settings, "services"))
  1019.     {
  1020.     firewall_settings = `VBox ();
  1021.     help = "";
  1022.     y2error ("Firewall services not specified");
  1023.     }
  1024.  
  1025.     map<string,any> ret = (map<string,any>)union ($[
  1026.     "widget" : `custom,
  1027.     "custom_widget" : firewall_settings,
  1028.     "help" : help,
  1029.     "init" : OpenFirewallInitWrapper,
  1030.     "store" : OpenFirewallStoreWrapper,
  1031.     "handle" : OpenFirewallHandleWrapper,
  1032.     "handle_events" : [ "_cwm_firewall_details", "_cwm_open_firewall" ],
  1033.     ], settings);
  1034.  
  1035.     return ret;
  1036. }
  1037.  
  1038. /**
  1039.  * Check if settings were modified by the user
  1040.  * @return boolean true if settings were modified
  1041.  */
  1042. global boolean Modified () {
  1043.     return SuSEFirewall::GetModified ();
  1044. }
  1045.  
  1046.  
  1047. // EOF
  1048. }
  1049.