2e082dfe |
1 | #!/usr/bin/perl |
2 | # udptunnel-reconf |
3 | # Set up the relevant stuff in /etc/userv/vpn, and then run |
4 | # this. It should tell you what to do to inittab and ipif-networks. |
5 | |
6 | # This is free software; you can redistribute it and/or modify it |
7 | # under the terms of the GNU General Public License as published by |
8 | # the Free Software Foundation; either version 2 of the License, or |
9 | # (at your option) any later version. |
10 | # |
11 | # This program is distributed in the hope that it will be useful, but |
12 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | # General Public License for more details. |
15 | # |
16 | # You should have received a copy of the GNU General Public License |
17 | # along with userv-utils; if not, write to the Free Software |
18 | # Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | # |
20 | # $Id$ |
21 | |
22 | use Socket; |
23 | |
24 | # @@@- |
25 | $shareuserv= "`pwd`"; |
26 | $etcvpn= "`pwd`"; |
27 | $varlibvpn= "`pwd`"; |
28 | # -@@@ |
29 | |
30 | sub badusage () { die "usage: udptunnel-reconf [<directory>]\n"; } |
31 | $debug=0; |
32 | |
33 | sub fault ($) { die "$0: $_[0]\n"; } |
34 | |
35 | while ($ARGV[0] =~ m/^-/) { |
36 | $_= shift @ARGV; |
37 | last if m/^--$/; |
38 | if (m/^-d$/) { $debug++; next; } |
39 | badusage(); |
40 | } |
41 | |
42 | if (@ARGV) { $etcvpn= shift @ARGV; } |
43 | badusage() if @ARGV; |
44 | |
45 | chdir $etcvpn or fault("$etcvpn: $!"); |
46 | |
47 | sub run_m4 ($$$) { |
48 | my ($wanted, $site, $variable) = @_; |
49 | $x= "m4 -P -DWANTED=$wanted -DWHVARIABLE=V_$variable -DV_global=global ". |
50 | "-DV_site=$site -DV_varlibvpn=$varlibvpn ". |
51 | "-DV_defaults=$shareuserv/udptunnel-vpn-defaults ". |
52 | "$shareuserv/udptunnel-vpn-config.m4"; |
53 | print STDERR $x,"\n" if $debug>=2; |
54 | open X, "$x |" or die $!; |
55 | undef $/; |
56 | $m4out= <X>; |
57 | $/= "\n"; |
58 | close X; $? and exit -1; |
59 | $m4out =~ s/^\s+//; |
60 | $m4out =~ s/\n+/\n/g; |
61 | $m4out =~ s/\s+$//; |
62 | print STDERR "$wanted/$variable($site) -> \`$m4out'\n" if $debug>=1; |
63 | # $m4out='' if $wanted eq 'VARIABLE' && substr($m4out,0,2) eq 'V_'; |
64 | return $m4out; |
65 | } |
66 | |
67 | sub check_junk ($$) { |
68 | my ($emsg, $site) = @_; |
69 | $j= run_m4('JUNK',$site,''); |
70 | $j =~ s/^\# //g; |
71 | fault("$emsg: $j") if length $j; |
72 | } |
73 | |
74 | sub var_global ($) { return run_m4('VARIABLE','',$_[0]) } |
75 | sub var_site ($) { return run_m4('VARIABLE',$site,$_[0]) } |
76 | |
77 | check_junk("error in config",''); |
78 | |
79 | @actives= split /\s+/, run_m4('ACTIVES','',''); |
80 | @passives= split /\s+/, run_m4('PASSIVES','',''); |
81 | |
82 | foreach $site (@actives, @passives) { |
83 | check_junk("error in config for site $site",$site); |
84 | } |
85 | |
86 | sub parse_addr_mask ($) { |
87 | my ($r) = @_; |
88 | my ($mask,$iaddr); |
89 | if ($r =~ s,/(\d+)$,,) { $mask=$1; } else { $mask=32; } |
90 | fault("invalid mask length $1") if $mask<0 || $mask>32; |
91 | $mask= $mask ? ~0 << (32-$mask) : 0; |
92 | $iaddr= inet_aton($r); fault("invalid address $r") unless defined $iaddr; |
93 | $iaddr= (unpack "N",$iaddr)[0]; |
94 | return ($iaddr, $mask); |
95 | } |
96 | |
2e082dfe |
97 | sub ipif_permit ($$$$) { |
98 | my ($group,$local,$net,$why) = @_; |
99 | my ($pmask,$piaddr,$fmask,$fiaddr,@lgroup,$lgid); |
100 | |
101 | @lgroup= getgrnam($group); |
102 | @lgroup or fault("invalid group \`$group' ($why)"); |
103 | $lgid= $lgroup[2]; |
104 | |
105 | if (!$local) { |
106 | ($piaddr,$pmask) = parse_addr_mask($net); |
107 | foreach $fref (@forbid_remote) { |
108 | ($fiaddr,$fmask) = @$fref; |
109 | $jmask= $fmask & $pmask; |
110 | #printf STDERR "%8lx %8lx %l8x %8lx", $pmask,$pmask |
111 | fault("local network $net claimed as remote ($why)") |
112 | if (($fiaddr&$jmask) == ($piaddr&$jmask)); |
113 | } |
114 | } |
115 | $ipif_file .= "$lgid,$local$net, $group, $why\n"; |
116 | } |
117 | |
118 | $glgroup= var_global('lgroup'); |
119 | $glend= var_site('lend')."/32"; |
120 | if ($glend !~ m/^V_/ && $glgroup !~ m/^V_/ && |
121 | length $glend && length $glgroup) { |
122 | ipif_permit($glgroup, '=', "$glend", 'local endpoint'); |
123 | } else { |
124 | $glend='X'; $glgroup='X'; |
125 | } |
126 | |
127 | foreach $site (@actives, @passives) { |
1c18e501 |
128 | $forbid_remote= var_site('forbid_remote'); |
129 | @forbid_remote= (); |
130 | if ($forbid_remote ne '-') { |
131 | foreach $r (split /[, \t]+/, $forbid_remote) { |
132 | push @forbid_remote, [ parse_addr_mask($r) ]; |
133 | } |
134 | } |
135 | |
2e082dfe |
136 | $tlend= var_site('lend')."/32"; |
137 | $tlgroup= var_site('lgroup'); |
138 | if ($tlend ne $glend || $tlgroup ne $glgroup) { |
139 | ipif_permit($tlgroup, '=', $tlend, "$site - local endpoint"); |
140 | } |
141 | $trend= var_site('rend').'/32'; |
142 | $ix= 0; |
143 | $trnets= var_site('rnets'); |
144 | ipif_permit($tlgroup, '', $trend, "$site - remote endpoint"); |
145 | if ($trnets ne '-') { |
146 | foreach $rnet (split /,/, $trnets) { |
147 | ipif_permit($tlgroup, '', $rnet, "$site - remote network #$ix"); |
148 | $ix++; |
149 | } |
150 | } |
151 | } |
152 | |
153 | sub write_file ($$$$) { |
154 | my ($fn,$why,$head,$body) = @_; |
155 | length $fn or fault("location to write $why not specified"); |
156 | open F, ">$fn.new" or fault("create $fn.new: $!"); |
157 | print F $head."\n# AUTOGENERATED BY $0 - DO NOT EDIT\n".$body or die $!; |
158 | close F or die $!; |
159 | rename "$fn.new",$fn or die $!; |
160 | } |
161 | |
162 | $ipifnetsfile= var_global(ipifnetsfile); |
163 | write_file($ipifnetsfile,'ipifnetsfile','', $ipif_file); |
164 | |
165 | $active_file= ''; |
99d1b3be |
166 | $knownhosts_file= ''; |
2e082dfe |
167 | $inittab= ''; |
168 | $ix= 0; |
169 | foreach $site (@actives) { |
170 | $active_file.= "$site\t".var_site('activesxinfo')."\n"; |
171 | $inittab.= sprintf("t%d", $ix++).':'.var_site('inittab_line')."\n"; |
99d1b3be |
172 | $hostkey= var_site('rhostkey'); |
173 | $knownhosts_file.= var_site('sshdest').' '.$hostkey."\n" |
174 | if length $hostkey; |
2e082dfe |
175 | $invoke_file= var_site('invoke_file'); |
176 | write_file($invoke_file, 'invoke_file', |
99d1b3be |
177 | var_site('invoke_head')."\n", var_site('invoke_body')); |
2e082dfe |
178 | chmod 0777&~umask, $invoke_file or die $!; |
179 | } |
99d1b3be |
180 | write_file(var_global('knownhostsfile'),'knownhostsfile', '',$knownhosts_file); |
2e082dfe |
181 | write_file(var_global('activesfile'),'activesfile', '',$active_file); |
182 | |
183 | print |
184 | "# You can cut and paste all or part of this into your inittab if you like:\n", |
185 | $inittab; |
186 | |
187 | print |
188 | "# And consider adding this line, or some of this file's contents,\n". |
189 | "# to your /etc/userv/ipif-networks:\n", |
190 | "$ipifnetsfile\n" |
191 | if $ipifnetsfile =~ m,^/,; |
192 | |
193 | $passive_file= ''; |
194 | foreach $site (@passives) { |
195 | $passive_file.= "$site\t".var_site('passivesxinfo')."\n"; |
196 | } |
197 | write_file(var_global('passivesfile'),'passivesfile', '',$passive_file); |
198 | |
199 | system var_global('postconfigure'); $? and exit -1; |
200 | |
201 | exit 0; |