e48049ab59d83e6850a42c59bf95e6061eab24d1
[hcoop/portal.git] / sec.mlt
1 <% val you = Init.getUserId ();
2 val yourname = Init.getUserName ();
3
4 val nodeNum = case $"node" of
5 "" => 4
6 | node => Web.stoi node;
7 val nodeName = Init.nodeName nodeNum;
8
9 val uname = case $"uname" of
10 "" => yourname
11 | uname => uname;
12
13 val socks = Sec.socketPerms {node = nodeNum, uname = uname};
14 val tpe = Sec.isTpe {node = nodeNum, uname = uname};
15 val cron = Sec.cronAllowed {node = nodeNum, uname = uname};
16
17 ref showNormal = true;
18
19 @header [("title", ["Security settings"])];
20
21 if $"cmd" = "socks" then
22 showNormal := false;
23 val socks = $"socks";
24 %>Are you sure you want to request that socket permissions for <b><% Web.html uname %></b> on <b><% Web.html nodeName %></b> be changed to <b><% Web.html socks %></b>?<br>
25 <a href="sec?cmd=socks2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&socks=<% Web.urlEncode socks %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
26 elseif $"cmd" = "socks2" then
27 val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat [uname, ": change socket permissions to ", $"socks"], msg = $"msg"};
28 if not (Sec.Req.notifyNew id) then
29 %><h3>Error sending e-mail notification</h3><%
30 end
31 %><h3>Request added</h3><%
32
33 elseif $"cmd" = "tpe" then
34 showNormal := false;
35 val tpe = iff $"tpe" = "yes" then "on" else "off";
36 %>Are you sure you want to request that trusted-path-executables-only for <b><% Web.html uname %></b> on <b><% Web.html nodeName %></b> be turned <b><% tpe %></b>?<br>
37 <a href="sec?cmd=tpe2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&tpe=<% tpe %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
38 elseif $"cmd" = "tpe2" then
39 val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat [uname, ": turn tpe ", $"tpe"], msg = $"msg"};
40 if not (Sec.Req.notifyNew id) then
41 %><h3>Error sending e-mail notification</h3><%
42 end
43 %><h3>Request added</h3><%
44
45 elseif $"cmd" = "cron" then
46 showNormal := false;
47 val cron = iff $"cron" = "yes" then "enabled" else "disabled";
48 %>Are you sure you want to request that <tt>cron</tt> permissions for <b><% Web.html uname %></b> on <b><% Web.html nodeName %></b> be <b><% cron %></b>?<br>
49 <a href="sec?cmd=cron2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&cron=<% cron %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
50 elseif $"cmd" = "cron2" then
51 val cron = iff $"cron" = "enabled" then "enable" else "disable";
52 val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat [uname, ": ", cron, " cron access"], msg = $"msg"};
53 if not (Sec.Req.notifyNew id) then
54 %><h3>Error sending e-mail notification</h3><%
55 end
56 %><h3>Request added</h3><%
57 elseif $"cmd" = "rule" then
58 showNormal := false;
59 val rule = $"rule";
60
61 if Sec.validRule rule then
62 %>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>
63 <a href="sec?cmd=rule2&node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&rule=<% Web.urlEncode rule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
64 else
65 %>"<% 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.<%
66 end
67
68 elseif $"cmd" = "rule2" then
69 val rule = $"rule";
70
71 if Sec.validRule rule then
72 val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Add firewall rule \"", nodeName, " ", uname, " ", rule, "\""], msg = $"msg"};
73 if not (Sec.Req.notifyNew id) then
74 %><h3>Error sending e-mail notification</h3><%
75 end
76 %><h3>Request added</h3><%
77 else
78 %>"<% 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.<%
79 end
80
81 elseif $"modRule" <> "" then
82 showNormal := false;
83 val oldRule = $"modRule";
84 val rule = $"rule"
85 if oldRule = rule then
86 %>You didn't modify the textbox for this rule before clicking the button, so there is no request to be made.<%
87 else
88 %>Are you sure you want to request that firewall rule <b><% Web.html uname %>&nbsp;<% Web.html oldRule %></b> be replaced by <b><% Web.html uname %>&nbsp;<% Web.html rule %></b> on <b><% Web.html nodeName %></b>?<br>
89 <a href="sec?node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&modRule2=<% Web.urlEncode oldRule %>&rule=<% Web.urlEncode rule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
90 end
91 elseif $"modRule2" <> "" then
92 val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Change firewall rule \"", uname, " ", $"modRule2", "\" to \"", uname, " ", $"rule", "\""], msg = $"msg"};
93 if not (Sec.Req.notifyNew id) then
94 %><h3>Error sending e-mail notification</h3><%
95 end
96 %><h3>Request added</h3><%
97
98 elseif $"delRule" <> "" then
99 showNormal := false;
100 val oldRule = $"delRule";
101 %>Are you sure you want to request that firewall rule <b><% Web.html uname %>&nbsp;<% Web.html oldRule %></b> on <b><% Web.html nodeName %></b> be <b>deleted</bD>?<br>
102 <a href="sec?node=<% nodeNum %>&uname=<% Web.urlEncode uname %>&delRule2=<% Web.urlEncode oldRule %>&msg=<% Web.urlEncode ($"msg") %>">Yes, place the request!</a><%
103 elseif $"delRule2" <> "" then
104 val id = Sec.Req.add {usr = you, node = nodeNum, data = String.concat ["Delete firewall rule \"", uname, " ", $"delRule2", "\""], msg = $"msg"};
105 if not (Sec.Req.notifyNew id) then
106 %><h3>Error sending e-mail notification</h3><%
107 end
108 %><h3>Request added</h3><%
109
110 elseif $"cmd" = "open" then
111 showNormal := false;
112 Group.requireGroupName "server";
113 %><h3>Open requests</h3>
114 <a href="sec?cmd=list">List all requests</a><%
115
116 foreach (name, req) in Sec.Req.listOpen () do %>
117 <br><hr><br>
118 <table class="blanks">
119 <tr> <td>By:</td> <td><a href="user?id=<% #usr req %>"><% name %></a></td> </tr>
120 <tr> <td>Time:</td> <td><% #stamp req %> (<% Util.diffFromNow (#stamp req) %> ago)</td></tr>
121 <tr> <td>Node:</td> <td><% Web.html (Init.nodeName (#node req)) %></td> </tr>
122 <tr> <td>Request:</td> <td><% #data req %></td> </tr>
123 <tr> <td>Msg:</td> <td colspan="2"><% Web.html (#msg req) %></td> </tr>
124 </table>
125
126 <br>
127 <a href="sec?mod=<% #id req %>">[Modify]</a>
128 <a href="sec?del=<% #id req %>">[Delete]</a><br>
129
130 <% end
131
132 elseif $"cmd" = "list" then
133 showNormal := false;
134 Group.requireGroupName "server"
135 %><h3>All requests</h3><%
136
137 foreach (name, req) in Sec.Req.list () do %>
138 <br><hr><br>
139 <table class="blanks">
140 <tr> <td>By:</td> <td colspan="2"><a href="user?id=<% #usr req %>"><% name %></a></td> </tr>
141 <tr> <td>Time:</td> <td colspan="2"><% #stamp req %> (<% Util.diffFromNow (#stamp req) %> ago)</td></tr>
142 <tr> <td>Node:</td> <td><% Web.html (Init.nodeName (#node req)) %></td> </tr>
143 <tr> <td>Request:</td> <td><% #data req %></td> </tr>
144 <tr> <td>Reason:</td> <td colspan="2"><% Web.html (#msg req) %></td> </tr>
145 </table>
146
147 <br>
148 <a href="sec?mod=<% #id req %>">[Modify]</a>
149 <a href="sec?del=<% #id req %>">[Delete]</a>
150
151 <% end
152
153 elseif $"mod" <> "" then
154 showNormal := false;
155 Group.requireGroupName "server";
156 val id = Web.stoi ($"mod");
157 val req = Sec.Req.lookup id;
158 val user = Init.lookupUser (#usr req) %>
159 <h3>Handle request</h3>
160
161 <form action="sec" method="post">
162 <input type="hidden" name="save" value="<% id %>">
163 <table class="blanks">
164 <tr> <td>Requestor:</td> <td><a href="user?id=<% #usr req %>"><% #name user %></a></td> </tr>
165 <tr> <td>Time:</td> <td><% #stamp req %> (<% Util.diffFromNow (#stamp req) %> ago)</td></tr>
166 <tr> <td>Status:</td> <td><select name="status">
167 <option value="0"<% if #status req = Sec.Req.NEW then %> selected<% end %>>New</option>
168 <option value="1"<% if #status req = Sec.Req.INSTALLED then %> selected<% end %>>Installed</option>
169 <option value="2"<% if #status req = Sec.Req.REJECTED then %> selected<% end %>>Rejected</option>
170 </select></td> </tr>
171 <tr> <td>Node:</td> <td><select name="node">
172 <% foreach node in Init.listNodes () do %>
173 <option value="<% #id node %>"<% if #id node = #node req then %> selected<% end %>><% Web.html (#name node) %> (<% Web.html (#descr node) %>)</option>
174 <% end %></select></td> </tr>
175 <tr> <td>Request:</td> <td><input name="req" value="<% Web.html (#data req) %>"></td> </tr>
176 <tr> <td>Message:</td> <td><textarea name="msg" rows="10" cols="80" wrap="soft"><% Web.html (#msg req) %></textarea></td> </tr>
177 <tr> <td><input type="submit" value="Save"></td> </tr>
178 </table>
179 </form>
180
181 <% elseif $"save" <> "" then
182 showNormal := false;
183 Group.requireGroupName "server";
184 val id = Web.stoi ($"save");
185 val req = Sec.Req.lookup id;
186 val oldStatus = #status req;
187 val newStatus = Sec.Req.statusFromInt (Web.stoi ($"status"));
188 Sec.Req.modify {req with node = nodeNum, data = $"req", msg = $"msg", status = newStatus};
189 if not (Sec.Req.notifyMod {old = oldStatus, new = newStatus, changer = Init.getUserName(), req = id}) then
190 %><h3>Error sending e-mail notification</h3><%
191 end
192 %><h3>Request modified</h3>
193 Back to: <a href="sec?cmd=open">open requests</a>, <a href="sec?cmd=list">all requests</a>
194
195 <% elseif $"del" <> "" then
196 showNormal := false;
197 Group.requireGroupName "server";
198 val id = Web.stoi ($"del");
199 val req = Sec.Req.lookup id;
200 val user = Init.lookupUser (#usr req)
201 %><h3>Are you sure you want to delete request by <% #name user %> for "<% #data req %>" on <% Web.html (Init.nodeName (#node req)) %>?</h3>
202 <a href="sec?del2=<% id %>">Yes, I'm sure!</a>
203
204 <% elseif $"del2" <> "" then
205 showNormal := false;
206 Group.requireGroupName "server";
207 val id = Web.stoi ($"del2");
208 Sec.Req.delete id
209 %><h3>Request deleted</b><h3>
210 Back to: <a href="sec?cmd=open">open requests</a>, <a href="sec?cmd=list">all requests</a>
211
212 <% end;
213
214 if showNormal then %>
215
216 <table class="blanks">
217 <form action="sec" method="post">
218 <input type="hidden" name="uname" value="<% Web.html uname %>">
219 <tr> <td>Machines:</td> <td><select name="node">
220 <% foreach node in Init.listNodes () do %>
221 <option value="<% #id node %>"<% if nodeNum = #id node then %> selected<% end %>><% Web.html (#name node) %> (<% Web.html (#descr node) %>)</option>
222 <% end %></select></td>
223 <td><input type="submit" value="Switch"></td> </tr>
224 </form>
225 <form action="sec" method="post">
226 <input type="hidden" name="node" value="<% nodeNum %>">
227 <tr> <td>Your users:</td> <td><select name="uname">
228 <% foreach name in (yourname :: Sec.findSubusers yourname) do %>
229 <option value="<% name %>"<% if uname = name then %> selected<% end %>><% name %></option>
230 <% end %></select></td>
231 <td><input type="submit" value="Switch"></td> </tr>
232 </form>
233 </table>
234
235 <!--h3>Request socket permissions change</h3>
236
237 <p>You need to request socket permissions before you are able to open any network connections. While you will be limited by firewall rules even then, any requests for firewall rules you enter in the "Reason" blank here <b>will be ignored</b>. Please use the separate form at the bottom of this page for that. There is no need to wait until a request for socket permissions has been granted before starting to request firewall rules.</p>
238
239 <p>Keep in mind that, if your request is granted, it will never apply to existing log-in sessions. Close them and re-connect to take advantage of your new privileges.</p>
240
241 <form action="sec" method="post">
242 <input type="hidden" name="node" value="<% nodeNum %>">
243 <input type="hidden" name="uname" value="<% uname %>">
244 <input type="hidden" name="cmd" value="socks">
245 <table class="blanks">
246 <tr> <td>New permissions:</td> <td><select name="socks">
247 <option value="none"<% if socks = Sec.NADA then %> selected<% end %>>None</option>
248 <option value="any"<% if socks = Sec.ANY then %> selected<% end %>>Any</option>
249 <option value="client"<% if socks = Sec.CLIENT_ONLY then %> selected<% end %>>Client only</option>
250 <option value="server"<% if socks = Sec.SERVER_ONLY then %> selected<% end %>>Server only</option>
251 </select></td> </tr>
252 <tr> <td>Reason:</td> <td><textarea name="msg" wrap="soft" rows="3" cols="80"></textarea></td> </tr>
253 <tr> <td><input type="submit" value="Request"></td> </tr>
254 </table>
255 </form>
256
257 <h3>Request change to your execute permissions</h3>
258
259 <form action="sec" method="post">
260 <input type="hidden" name="node" value="<% nodeNum %>">
261 <input type="hidden" name="uname" value="<% uname %>">
262 <input type="hidden" name="cmd" value="tpe">
263 <table class="blanks">
264 <tr> <td>Trusted path executables only?</td> <td><select name="tpe">
265 <option value="no"<% if not tpe then %> selected<% end %>>No</option>
266 <option value="yes"<% if tpe then %> selected<% end %>>Yes</option>
267 </select></td> </tr>
268 <tr> <td>Reason:</td> <td><textarea name="msg" wrap="soft" rows="3" cols="80"></textarea></td> </tr>
269 <tr> <td><input type="submit" value="Request"></td> </tr>
270 </table>
271 </form-->
272
273 <h3>Request change to your <tt>cron</tt> permissions</h3>
274
275 <form action="sec" method="post">
276 <input type="hidden" name="node" value="<% nodeNum %>">
277 <input type="hidden" name="uname" value="<% uname %>">
278 <input type="hidden" name="cmd" value="cron">
279 <table class="blanks">
280 <tr> <td>Allowed to use cron?</td> <td><select name="cron">
281 <option value="no"<% if not cron then %> selected<% end %>>No</option>
282 <option value="yes"<% if cron then %> selected<% end %>>Yes</option>
283 </select></td> </tr>
284 <tr> <td>Reason:</td> <td><textarea name="msg" wrap="soft" rows="3" cols="80"></textarea></td> </tr>
285 <tr> <td><input type="submit" value="Request"></td> </tr>
286 </table>
287 </form>
288
289 <% val rules = Sec.findFirewallRules {node = nodeNum, uname = uname};
290 switch rules of
291 _::_ => %>
292 <h3>Your firewall rules</h3>
293
294 <% foreach rule in rules do %>
295 <form action="sec" method="post">
296 <input type="hidden" name="node" value="<% nodeNum %>">
297 <input type="hidden" name="uname" value="<% uname %>">
298 <input type="hidden" name="modRule" value="<% Web.html rule %>">
299 <label>Node: <% nodeName %> <input name="rule" value="<% Web.html rule %>"></label>
300 <a href="sec?delRule=<% Web.urlEncode rule %>">[Request deletion]</a>
301 <input type="submit" value="Request change">
302 </form><br>
303 <% end
304 end%>
305
306 <h3>Request a new firewall rule</h3>
307
308 <p>You can find a description of rule formats <a href="http://wiki.hcoop.net/FirewallRules">on our wiki</a>. Enter here the rule you want, without the initial <tt>user</tt> portion. We also <a href="http://wiki.hcoop.net/FirewallRules#Common_Rules">allow all members access to some services</a> if they are commonly requested.</p>
309
310 <p>When requesting a <tt>Server</tt> or <tt>ProxiedServer</tt> rule, use a port above <tt>50000</tt> (there is a list of <a href="http://wiki.hcoop.net/AllocatedFirewallPorts">allocated ports</a>). We may grant <tt>Server</tt> requests for ports under <tt>50000</tt> if it can be justified, but never for a <tt>ProxiedServer</tt>.</p>
311
312 <p>We very rarely grant requests for Client rules that don't include remote host whitelists. For example, important security concerns make it a bad idea for us to give anybody blanket IRC permissions. Instead, request specific servers. We will refuse such requests that include networks that are popularly considered fronts for illegal activity.</p>
313
314 <form action="sec" method="post">
315 <input type="hidden" name="node" value="<% nodeNum %>">
316 <input type="hidden" name="uname" value="<% uname %>">
317 <input type="hidden" name="cmd" value="rule">
318 <table class="blanks">
319 <tr> <td>Rule</td> <td><input name="rule" size="80"></td> </tr>
320 <tr> <td>Reason:</td> <td><textarea name="msg" wrap="soft" rows="3" cols="80"></textarea></td> </tr>
321 <tr> <td><input type="submit" value="Request"></td> </tr>
322 </table>
323 </form>
324
325 <% end %>
326
327 <% @footer[] %>