#!/usr/bin/perl
+use Socket;
+
#$sharedir= '/usr/local/share/userv/udptunnelconf';
$sharedir= '/home/ian/things/userv-utils/udptunnelconf';
$confdir= '/etc/udptunnel';
sub badusage () { die "usage: udptunnel-reconf [<directory>]\n"; }
$debug=0;
+sub fault ($) { die "$0: $_[0]\n"; }
+
while ($ARGV[0] =~ m/^-/) {
$_= shift @ARGV;
last if m/^--$/;
}
if (@ARGV) { $confdir= shift @ARGV; }
-#badusage() if @ARGV;
+badusage() if @ARGV;
-chdir $confdir or die "$0: $confdir: $!\n";
+chdir $confdir or fault("$confdir: $!");
sub run_m4 ($$$) {
my ($wanted, $site, $variable) = @_;
"-DV_site=$site ".
"-DV_defaults=$sharedir/defaults $sharedir/config.m4";
print STDERR $x,"\n" if $debug>=2;
- open X, "$x |"
- or die $!;
+ open X, "$x |" or die $!;
undef $/;
$m4out= <X>;
$/= "\n";
$m4out =~ s/\n+/\n/g;
$m4out =~ s/\s+$//;
print STDERR "$wanted/$variable($site) -> \`$m4out'\n" if $debug>=1;
+# $m4out='' if $wanted eq 'VARIABLE' && substr($m4out,0,2) eq 'V_';
return $m4out;
}
my ($emsg, $site) = @_;
$j= run_m4('JUNK',$site,'');
$j =~ s/^\# //g;
- die "$0: $emsg: $j\n" if length $j;
+ fault("$emsg: $j") if length $j;
}
+sub var_global ($) { return run_m4('VARIABLE','',$_[0]) }
+sub var_site ($) { return run_m4('VARIABLE',$site,$_[0]) }
+
check_junk("error in config",'');
@actives= split /\s+/, run_m4('ACTIVES','','');
check_junk("error in config for site $site",$site);
}
-$_= run_m4('VARIABLE','greenend','command');
-s/\\\n/ /g;
-s/\s+/\n/g;
-print $_,"\n" or die $!;
+$lgroup= var_global('lgroup');
+@lgroup= getgrnam($lgroup);
+@lgroup or fault("invalid group $lgroup");
+$lgid= $lgroup[2];
+$forbid_remote= var_global('forbid_remote');
+@forbid_remote= ();
+
+sub parse_addr_mask ($) {
+ my ($r) = @_;
+ my ($mask,$iaddr);
+ if ($r =~ s,/(\d+)$,,) { $mask=$1; } else { $mask=32; }
+ fault("invalid mask length $1") if $mask<0 || $mask>32;
+ $mask= $mask ? ~0 << (32-$mask) : 0;
+ $iaddr= inet_aton($r); fault("invalid address $r") unless defined $iaddr;
+ $iaddr= (unpack "N",$iaddr)[0];
+ return ($iaddr, $mask);
+}
+
+foreach $r (split /[, \t]+/, $forbid_remote) {
+ push @forbid_remote, [ parse_addr_mask($r) ];
+}
+
+sub ipif_permit ($$$) {
+ my ($local,$net,$why) = @_;
+ my ($pmask,$piaddr,$fmask,$fiaddr);
+ if (!$local) {
+ ($piaddr,$pmask) = parse_addr_mask($net);
+ foreach $fref (@forbid_remote) {
+ ($fiaddr,$fmask) = @$fref;
+ $jmask= $fmask & $pmask;
+#printf STDERR "%8lx %8lx %l8x %8lx", $pmask,$pmask
+ fault("local network $net claimed as remote ($why) by $site")
+ if (($fiaddr&$jmask) == ($piaddr&$jmask));
+ }
+ }
+ $ipif_file .= "$lgid,$local$net, $lgroup, $why\n";
+}
+
+$glend= var_site('lend')."/32";
+if ($glend !~ m/^V_/) {
+ ipif_permit('=', "$glend", 'local endpoint');
+}
+
+foreach $site (@actives, @passives) {
+ $tlend= var_site('lend')."/32";
+ if ($tlend != $glend) {
+ ipif_permit('=', $tlend.'/32', "$site - local endpoint");
+ }
+ $trend= var_site('rend').'/32';
+ $ix= 0;
+ $trnets= var_site('rnets');
+ ipif_permit('', $trend, "$site - remote endpoint");
+ if ($trnets ne '-') {
+ foreach $rnet (split /,/, $trnets) {
+ ipif_permit('', $rnet, "$site - remote network #$ix");
+ $ix++;
+ }
+ }
+}
+
+sub write_file ($$$$) {
+ my ($fn,$why,$head,$body) = @_;
+ length $fn or fault("location to write $why not specified");
+ open F, ">$fn.new" or fault("create $fn.new: $!");
+ print F $head."\n# AUTOGENERATED BY $0 - DO NOT EDIT\n".$body or die $!;
+ close F or die $!;
+ rename "$fn.new",$fn or die $!;
+}
+
+write_file(var_global(ipifnetsfile),'ipifnetsfile','', $ipif_file);
+
+$active_file= '';
+$inittab= '';
+$ix= 0;
+foreach $site (@actives) {
+ $active_file.= "$site\t".var_site('activesxinfo')."\n";
+ $inittab.= sprintf("t%d", $ix++).':'.var_site('inittab_line')."\n";
+ write_file(var_site('invoke_file'), 'invoke_file',
+ var_site('invoke_head'),
+ var_site('invoke_body'));
+}
+write_file(var_global('activesfile'),'activesfile', '',$active_file);
+write_file(var_global('inittab_fragfile'),'inittab_fragfile',
+"# You can cut and paste all or part of this into your inittab if you like.",
+ $inittab);
+
+$passive_file= '';
+foreach $site (@passives) {
+ $passive_file.= "$site\t".var_site('passivesxinfo')."\n";
+}
+write_file(var_global('passivesfile'),'passivesfile', '',$passive_file);
+
+system var_global('postconfigure'); $? and exit -1;
+
+exit 0;
SET( lcommand, [udptunnel])
-SET( crypto, [-e nonce -e timestamp/10/30 -e pkcs5/8 \
- -e blowfish-cbcmac/128 -e blowfish-cbc/128])
+SET( crypto,
+ [-e nonce -e timestamp/10/30 -e pkcs5/8 \
+ -e blowfish-cbcmac/128 -e blowfish-cbc/128])
SET( lpublic, [`hostname`])
SET( lport, [Any])
SET( timeouts, [V_to_poll,V_to_quit,V_to_report])
SET( lnets, [-])m4_dnl often overridden in global
SET( rnets, [-])m4_dnl often overridden in sites
+SET( forbid_remote, [V_lnets])
SET( rcommandprefix, [])
SET( rcommand, [V_rcommandprefix udptunnel])
-SET( sshopts, [-o 'ForwardAgent no' -o 'ForwardX11 no' \
- -o 'BatchMode yes' -o 'ProtocolKeepAlives 300'])
-SET( ssh, [ssh -v V_sshopts])
+SET( sshprotoka, [-o 'ProtocolKeepAlives 300'])
+SET( sshstdopts, [-o 'ForwardAgent no' -o 'ForwardX11 no' -o 'BatchMode yes'])
+SET( sshverbose, [-v])
+SET( ssh,
+ [ssh V_sshstdopts \
+ V_sshprotoka V_sshverbose])
+
SET( sshdest, [V_rpublic])
SET( sites, [sites])
SET( tunnels, [tunnels])
+SET( varlib, [/var/lib/udptunnel-vpn])
+
+SET( ipifnetsfile, [V_varlib/ipif-networks])
+SET( activesfile, [V_varlib/active-sites])
+SET( activesxinfo, [])
+SET( passivesfile, [passive-sites])
+SET( passivesxinfo, [])
+
+SET( postconfigure, [])
+
+SET( invoke_file, [V_varlib/V_site.command])
+SET( invoke_head, [#!/bin/sh])
+SET( invoke_hook, [])
+
+SET( syslog_facility, local2)
+SET( syslog_priority, info)
+
+SET( inittab_runlevels, 2345)
+SET( inittab_fragfile, [inittab-fragment])
+SET( inittab_pfx, [])
+SET( inittab_sfx,
+ [2>&1 | logger -p V_syslog_facility.V_syslog_priority -t tunnel-V_site])
+SET( inittab_command,[V_inittab_pfx V_invoke_file V_inittab_sfx])
+SET( inittab_line, [V_inittab_runlevels:respawn:V_inittab_command])
+
+SET( invoke_body,
+[set -e
+V_invoke_hook
+echo "STARTING TUNNEL `date`" >&2
+V_command
+rc=$?
+echo "TUNNEL CLOSED rc=$rc" >&2
+exit $rc
+])
+
m4_dnl lgroup -- usually set in global
-SET( command, [ \
- V_lcommand \
- V_crypto \
- V_lpublic,V_lport V_rpublic,V_rport \
- V_lend,V_rend,V_mtu,V_proto \
- V_timeouts \
- V_rnets V_lnets \
- V_ssh V_ruser@V_sshdest V_rcommand
- ])
+SET( command,
+[V_lcommand \
+ V_crypto \
+ V_lpublic,V_lport \
+ V_rpublic,V_rport \
+ V_lend,V_rend,V_mtu,V_proto \
+ V_timeouts \
+ V_rnets \
+ V_lnets \
+ V_ssh \
+ V_ruser@V_sshdest \
+ V_rcommand
+ ])