+fun formatPorts ports = "(" ^ String.concatWith " " (map Int.toString ports) ^ ")"
+fun formatHosts hosts = "(" ^ String.concatWith " " hosts ^ ")"
+
+fun formatOutputRule (Client (ports, hosts)) = "dport " ^ formatPorts ports ^ (case hosts of
+ [] => ""
+ | _ => " daddr " ^ formatHosts hosts) ^ " ACCEPT;"
+
+fun formatInputRule (Server (ports, hosts)) = "dport " ^ formatPorts ports ^ (case hosts of
+ [] => ""
+ | _ => " saddr " ^ formatHosts hosts) ^ " ACCEPT;"
+
+type ferm_lines = { input_rules : (string list) DataStructures.StringMap.map,
+ output_rules : (string list) DataStructures.StringMap.map }
+
+fun generateNodeFermRules rules =
+ let
+ fun filter_node_rules rules =
+ List.filter (fn (uname, FirewallNode node, rule) => node = Slave.hostname () orelse case rule of
+ ProxiedServer _ => List.exists (fn (h,_) => h = Slave.hostname ()) Config.Apache.webNodes_all
+ | _ => false)
+ rules
+
+ val inputLines = ref StringMap.empty
+ val outputLines = ref StringMap.empty
+
+ fun confLine r (User uname, line) =
+ let
+ val line = "\t" ^ line ^ "\n"
+ val lines = case StringMap.find (!r, uname) of
+ NONE => []
+ | SOME lines => lines
+ in
+ r := StringMap.insert (!r, uname, line :: lines)
+ end
+
+ fun confLine_in (uname, rule) = confLine inputLines (uname, formatInputRule rule)
+ fun confLine_out (uname, rule) = confLine outputLines (uname, formatOutputRule rule)
+
+ fun insertConfLine (uname, ruleNode, rule) =
+ case rule of
+ Client (ports, hosts) => confLine_out (uname, rule)
+ | Server (ports, hosts) => confLine_in (uname, rule)
+ | LocalServer ports => (insertConfLine (uname, ruleNode, Client (ports, ["127.0.0.1/8"]));
+ insertConfLine (uname, ruleNode, Server (ports, ["127.0.0.1/8"])))
+ | ProxiedServer ports => if (fn FirewallNode r => r) ruleNode = Slave.hostname () then
+ (insertConfLine (uname, ruleNode, Server (ports, ["$WEBNODES"]));
+ insertConfLine (uname, ruleNode, Client (ports, [(fn FirewallNode r => r) ruleNode])))
+ else (* we are a web server *)
+ (insertConfLine (uname, ruleNode, Client (ports, [(fn FirewallNode r => r) ruleNode]));
+ insertConfLine (User "www-data", ruleNode, Client (ports, [(fn FirewallNode r => r) ruleNode])))
+
+ val _ = map insertConfLine (filter_node_rules rules)
+ in
+ { input_rules = !inputLines,
+ output_rules = !outputLines }
+
+
+ end