3 Parses /etc/hosts.{allow,deny}
5 Author: Raphael Pinson <raphink@gmail.com>
8 This lens tries to keep as close as possible to `man 5 hosts_access` and `man 5 hosts_options` where possible.
11 This file is licenced under the LGPL v2+, like the rest of Augeas.
16 About: Configuration files
17 This lens applies to /etc/hosts.{allow,deny}. See <filter>.
24 (************************************************************************
25 * Group: USEFUL PRIMITIVES
26 *************************************************************************)
29 let colon = del /[ \t]*(\\\\[ \t]*\n[ \t]+)?:[ \t]*(\\\\[ \t]*\n[ \t]+)?/ ": "
31 (* Variable: comma_sep *)
32 let comma_sep = /([ \t]|(\\\\\n))*,([ \t]|(\\\\\n))*/
34 (* Variable: ws_sep *)
38 let list_sep = del ( comma_sep | ws_sep ) ", "
41 let list_item = store ( Rx.word - /EXCEPT/i )
43 (* View: client_host_item
44 Allows @ for netgroups, supports [ipv6] syntax *)
45 let client_host_item =
46 let client_hostname_rx = /[A-Za-z0-9_.@?*-][A-Za-z0-9_.?*-]*/ in
47 let client_ipv6_rx = "[" . /[A-Za-z0-9:?*%]+/ . "]" in
48 let client_host_rx = client_hostname_rx | client_ipv6_rx in
49 let netmask = [ Util.del_str "/" . label "netmask" . store Rx.word ] in
50 store ( client_host_rx - /EXCEPT/i ) . netmask?
52 (* View: client_file_item *)
53 let client_file_item =
54 let client_file_rx = /\/[^ \t\n,:]+/ in
55 store ( client_file_rx - /EXCEPT/i )
57 (* Variable: option_kw
58 Since either an option or a shell command can be given, use an explicit list
59 of known options to avoid misinterpreting a command as an option *)
60 let option_kw = "severity"
74 (* Variable: shell_command_rx *)
75 let shell_command_rx = /[^ \t\n:][^\n]*[^ \t\n]|[^ \t\n:\\\\]/
76 - ( option_kw . /.*/ )
79 Allows escaped colon sequences *)
80 let sto_to_colon = store /[^ \t\n:=][^\n:]*((\\\\:|\\\\[ \t]*\n[ \t]+)[^\n:]*)*[^ \\\t\n:]|[^ \t\n:\\\\]/
83 * The except operator makes it possible to write very compact rules.
85 let except (lns:lens) = [ label "except" . Sep.space
86 . del /except/i "EXCEPT"
89 (************************************************************************
91 *************************************************************************)
95 let host = [ label "host"
103 A list of <daemon>s *)
104 let daemon_list = Build.opt_list daemon list_sep
108 let user = [ label "user"
110 . Util.del_str "@" ] in
115 (* View: client_file *)
116 let client_file = [ label "file" . client_file_item ]
119 A list of <client>s *)
120 let client_list = Build.opt_list ( client | client_file ) list_sep
123 Optional extensions defined in hosts_options(5) *)
124 let option = [ key option_kw
125 . ( del /([ \t]*=[ \t]*|[ \t]+)/ " " . sto_to_colon )? ]
127 (* View: shell_command *)
128 let shell_command = [ label "shell_command"
129 . store shell_command_rx ]
132 let entry = [ seq "line"
134 . (except daemon_list)?
137 . (except client_list)?
138 . ( (colon . option)+ | (colon . shell_command)? )
141 (************************************************************************
142 * Group: LENS AND FILTER
143 *************************************************************************)
146 let lns = (Util.empty | Util.comment | entry)*
149 let filter = incl "/etc/hosts.allow"
150 . incl "/etc/hosts.deny"
152 let xfm = transform lns filter