Add syntax checking of proposed firewall rules
authoradamch <adamch>
Sun, 25 Feb 2007 22:23:48 +0000 (22:23 +0000)
committeradamch <adamch>
Sun, 25 Feb 2007 22:23:48 +0000 (22:23 +0000)
sec.mlt
sec.sig
sec.sml
tables.sql

diff --git a/sec.mlt b/sec.mlt
index 8885eaa..7afdced 100644 (file)
--- a/sec.mlt
+++ b/sec.mlt
@@ -72,14 +72,26 @@ elseif $"cmd" = "ftp2" then
 elseif $"cmd" = "rule" then
        showNormal := false;
        val rule = $"rule";
-       %>Are you sure you want to request the firewall rule <b><% Web.html uname %>&nbsp;<% Web.html rule %></b> on <b><% Web.html nodeName %></b>?<br>
+
+       if Sec.validRule rule then
+               %>Are you sure you want to request the firewall rule <b><% Web.html uname %>&nbsp;<% Web.html rule %></b> on <b><% Web.html nodeName %></b>?<br>
        <a href="sec?cmd=rule2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&rule=<% Web.urlEncode rule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
+       else
+               %>"<% Web.html rule %>" is not a valid firewall rule! Please reread <a href="http://wiki.hcoop.net/wiki/FirewallRules">the instructions</a>, and remember to leave off the initial username portion.<%
+       end
+
 elseif $"cmd" = "rule2" then
-       val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Add firewall rule \"", uname, " ", $"rule", "\""], msg = $"msg"};
-       if not (Sec.Req.notifyNew id) then
-               %><h3>Error sending e-mail notification</h3><%
+       val rule = $"rule";
+
+       if Sec.validRule rule then
+               val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Add firewall rule \"", uname, " ", rule, "\""], msg = $"msg"};
+               if not (Sec.Req.notifyNew id) then
+                       %><h3>Error sending e-mail notification</h3><%
+               end
+               %><h3>Request added</h3><%
+       else
+               %>"<% Web.html rule %>" is not a valid firewall rule! Please reread <a href="http://wiki.hcoop.net/wiki/FirewallRules">the instructions</a>, and remember to leave off the initial username portion.<%
        end
-       %><h3>Request added</h3><%
 
 elseif $"modRule" <> "" then
        showNormal := false;
diff --git a/sec.sig b/sec.sig
index a282b37..2ab3bbd 100644 (file)
--- a/sec.sig
+++ b/sec.sig
@@ -15,4 +15,6 @@ signature SEC = sig
     val ftpAllowed : {node : int, uname : string} -> bool
 
     val findFirewallRules : {node : int, uname : string} -> string list
+
+    val validRule : string -> bool
 end
diff --git a/sec.sml b/sec.sml
index 782fdf7..b064a5f 100644 (file)
--- a/sec.sml
+++ b/sec.sml
@@ -95,4 +95,48 @@ fun findFirewallRules {node, uname} =
            []
     end
 
+fun intFromString s =
+    if CharVector.all Char.isDigit s andalso size s > 0 then
+       Int.fromString s
+    else
+       NONE
+
+fun validPort port =
+    case intFromString port of
+       NONE => false
+      | SOME n => n > 0
+
+fun validPortPiece pp =
+    case String.fields (fn ch => ch = #":") pp of
+       [port] => validPort port
+      | [port1, port2] => validPort port1 andalso validPort port2
+
+fun validPorts ports =
+    List.all validPortPiece (String.fields (fn ch => ch = #",") ports)
+
+fun validIp s =
+    case map intFromString (String.fields (fn ch => ch = #".") s) of
+        [SOME n1, SOME n2, SOME n3, SOME n4] =>
+        n1 >= 0 andalso n1 < 256 andalso n2 >= 0 andalso n2 < 256 andalso n3 >= 0 andalso n3 < 256 andalso n4 >= 0 andalso n4 < 256
+      | _ => false
+
+fun isIdent ch = Char.isLower ch orelse Char.isDigit ch
+
+fun validHost s =
+    size s > 0 andalso size s < 20
+    andalso CharVector.all (fn ch => isIdent ch orelse ch = #"-") s
+
+fun validDomain s =
+    size s > 0 andalso size s < 100
+    andalso List.all validHost (String.fields (fn ch => ch = #".") s)
+
+val validHosts = List.all (fn x => validIp x orelse validDomain x)
+
+fun validRule rule =
+    case String.tokens Char.isSpace rule of
+       "Client" :: ports :: hosts => validPorts ports andalso validHosts hosts
+      | "Server" :: ports :: hosts => validPorts ports andalso validHosts hosts
+      | ["LocalServer", ports] => validPorts ports
+      | _ => false
+
 end
index cc2ff98..e28196a 100644 (file)
@@ -225,7 +225,8 @@ CREATE TABLE Apt(
        msg TEXT NOT NULL,
        status INTEGER NOT NULL,
        stamp TIMESTAMP NOT NULL,
-       FOREIGN KEY (usr) REFERENCES WebUser(id) ON DELETE CASCADE);
+       FOREIGN KEY (usr) REFERENCES WebUser(id) ON DELETE CASCADE,
+       FOREIGN KEY (node) REFERENCES WebNode(id) ON DELETE CASCADE);
 
 CREATE SEQUENCE AptSeq START 1;
 
@@ -303,6 +304,7 @@ CREATE TABLE Sec(
        msg TEXT NOT NULL,
        status INTEGER NOT NULL,
        stamp TIMESTAMP NOT NULL,
-       FOREIGN KEY (usr) REFERENCES WebUser(id) ON DELETE CASCADE);
+       FOREIGN KEY (usr) REFERENCES WebUser(id) ON DELETE CASCADE,
+       FOREIGN KEY (node) REFERENCES WebNode(id) ON DELETE CASCADE);
 
 CREATE SEQUENCE SecSeq START 1;