From 32600d5467b3290daa0e2ffc718f147071a66c6d Mon Sep 17 00:00:00 2001 From: Darryl Quinn Date: Wed, 1 Apr 2015 10:42:53 -0500 Subject: [PATCH] initial deploy --- files/etc/hotplug.d/iface/13-vtun | 21 ++ files/etc/init.d/vtund | 138 +++++++ files/etc/init.d/vtundsrv | 118 ++++++ files/etc/mesh-release | 2 +- files/usr/local/bin/vtun_up | 128 +++++++ files/www/cgi-bin/tunfunc.pm | 148 ++++++++ files/www/cgi-bin/ucifunc.pm | 42 +++ files/www/cgi-bin/vpn | 575 ++++++++++++++++++++++++++++++ files/www/cgi-bin/vpnc | 449 +++++++++++++++++++++++ 9 files changed, 1620 insertions(+), 1 deletion(-) create mode 100644 files/etc/hotplug.d/iface/13-vtun create mode 100755 files/etc/init.d/vtund create mode 100755 files/etc/init.d/vtundsrv create mode 100644 files/usr/local/bin/vtun_up create mode 100644 files/www/cgi-bin/tunfunc.pm create mode 100644 files/www/cgi-bin/ucifunc.pm create mode 100755 files/www/cgi-bin/vpn create mode 100755 files/www/cgi-bin/vpnc diff --git a/files/etc/hotplug.d/iface/13-vtun b/files/etc/hotplug.d/iface/13-vtun new file mode 100644 index 00000000..ae05feda --- /dev/null +++ b/files/etc/hotplug.d/iface/13-vtun @@ -0,0 +1,21 @@ +#!/bin/sh + +# Handles setting up rules for tunnel interfaces +#echo "Interface is $INTERFACE $ACTION" >> /tmp/vtundscript.log +ISVPN=false +case "$INTERFACE" in + vpn*) + ISVPN=true; + ;; +esac + +if [ "$ISVPN" = true ]; then + INTF=tun${INTERFACE:3} + if [ $ACTION = "ifup" ] ; then + /usr/local/bin/vtun_up $INTF up + # echo "$INTF up" >> /tmp/vtundscript.log + elif [ $ACTION = "ifdown" ] ; then + /usr/local/bin/vtun_up $INTF down + # echo "$INTF down" >> /tmp/vtundscript.log + fi +fi diff --git a/files/etc/init.d/vtund b/files/etc/init.d/vtund new file mode 100755 index 00000000..04e99c4d --- /dev/null +++ b/files/etc/init.d/vtund @@ -0,0 +1,138 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=84 +STOP=85 + +CLIENT_CONF=/etc/vtund.conf + +# Starting tun interface is tun50 +TUNNUM=60 +MAXTUNNUM=69 + +######### UTILITY FUNCTIONS ########### +# return the number of "type" sections +uci_type_count() { + local t="$1" + local rc="$2" + local count=`uci show vtun|egrep "@$t\[.\]=$t"|wc -l` + eval "$rc=$count" +} + +######### UTILITY FUNCTIONS END ########### + +options_config() { + local cfg="$1" + local new_file="$2" + local port timeout syslog ppp ifconfig route firewall ip + + config_get port "$cfg" port "5525" + config_get timeout "$cfg" timeout "60" + config_get syslog "$cfg" syslog "daemon" + config_get ppp "$cfg" ppp "/usr/sbin/pppd" + config_get ifconfig "$cfg" ifconfig "/sbin/ifconfig" + config_get route "$cfg" route "/sbin/route" + config_get firewall "$cfg" firewall "/usr/sbin/iptables" + config_get ip "$cfg" ip "/sbin/ip" + + echo "options {" >> $new_file + echo " port $port;" >> $new_file + echo " timeout $timeout;" >> $new_file + echo " syslog $syslog;" >> $new_file + echo " ppp $ppp;" >> $new_file + echo " ifconfig $ifconfig;" >> $new_file + echo " route $route;" >> $new_file + echo " firewall $firewall;" >> $new_file + echo " ip $ip;" >> $new_file + echo "}" >> $new_file + echo " " >> $new_file +} + + + +# CONNECT THIS CLIENT TO A SERVER +to_server_config() { + local cfg="$1" + local new_file="$2" + local enabled host pwd net node netip clientip serverip + + if [ $TUNNUM -lt $MAXTUNNUM ] + then + config_get_bool enabled "$cfg" enabled + config_get node "$cfg" node + config_get host "$cfg" host + config_get passwd "$cfg" passwd + config_get netip "$cfg" netip + config_get clientip "$cfg" clientip + config_get serverip "$cfg" serverip + + if [ $enabled -eq 1 ] + then + echo "$node {" >> $new_file + echo " passwd $passwd;" >> $new_file + echo " device tun${TUNNUM};" >> $new_file + echo " up {" >> $new_file + echo -e " ifconfig \"%% ${clientip} netmask 255.255.255.252 pointopoint ${serverip} mtu 1450\";" >> $new_file + echo -e " route \"add -net ${netip}/30 gw ${serverip}\";" >> $new_file + echo " };" >> $new_file + echo " down {" >> $new_file + echo " };" >> $new_file + echo "}" >> $new_file + echo " " >> $new_file + TUNNUM=$(( TUNNUM + 1 )) + fi + else + echo "## TOO MANY TUNNEL CONNECTIONS (${TUNNUM}) ##" >> $new_file + fi +} + +start_clients() { + local cfg="$1" + local new_file="$2" + local enabled host pwd net node netip clientip serverip + config_get_bool enabled "$cfg" enabled + + if [ $enabled -eq 1 ] + then + config_get node "$cfg" node + config_get host "$cfg" host + /usr/sbin/vtund -p -f $CLIENT_CONF ${node} $host + fi +} + +apply_uci_config() { + sh -c '. /lib/functions.sh; include /lib/config; uci_apply_defaults' +} + +start() { + # only if vtun is installed + if [[ -x "/usr/sbin/vtund" ]] + then + apply_uci_config + config_load vtun + + # Remove the current vtun config file + rm -f $CLIENT_CONF + + # config_foreach network_config network + config_foreach options_config options "$CLIENT_CONF" + config_foreach to_server_config server "$CLIENT_CONF" + + # STARTUP CLIENT TO SERVER CONNECTIONS + config_foreach start_clients server "$CLIENT_CONF" + fi +} + +stop() { + # only if vtun is installed + if [[ -x "/usr/sbin/vtund" ]] + then + # find all the vtund CLIENT processess... + #for x in `ps -w|grep -F 'vtund[c]:'|grep -v grep|tr -s ' '|cut -d' ' -f2` + #do + # s=`echo $s $x` + #done + #kill $s + killall vtund + fi +} diff --git a/files/etc/init.d/vtundsrv b/files/etc/init.d/vtundsrv new file mode 100755 index 00000000..2e91c7db --- /dev/null +++ b/files/etc/init.d/vtundsrv @@ -0,0 +1,118 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=82 +STOP=83 + +SERVER_CONF=/var/etc/vtundsrv.conf +# Starting tun interface is tun50 +TUNNUM=50 +MAXTUNNUM=59 + +network_config() { + local cfg="$1" + local start def_net + # generate the default net + def_net='172.31.1.1' + config_get start "$cfg" start $def_net + echo "NETWORK: $start" >> /tmp/vtuntest.log +} + +options_config() { + local cfg="$1" + local new_file="$2" + local port timeout syslog ppp ifconfig route firewall ip + + config_get port "$cfg" port "5525" + config_get timeout "$cfg" timeout "60" + config_get syslog "$cfg" syslog "daemon" + config_get ppp "$cfg" ppp "/usr/sbin/pppd" + config_get ifconfig "$cfg" ifconfig "/sbin/ifconfig" + config_get route "$cfg" route "/sbin/route" + config_get firewall "$cfg" firewall "/usr/sbin/iptables" + config_get ip "$cfg" ip "/sbin/ip" + + echo "options {" >> $new_file + echo " port $port;" >> $new_file + echo " timeout $timeout;" >> $new_file + echo " syslog $syslog;" >> $new_file + echo " ppp $ppp;" >> $new_file + echo " ifconfig $ifconfig;" >> $new_file + echo " route $route;" >> $new_file + echo " firewall $firewall;" >> $new_file + echo " ip $ip;" >> $new_file + echo "}" >> $new_file + echo " " >> $new_file +} + +# ALLOW THESE CLIENTS TO CONNECT TO THIS SERVER vtundsrv.conf +allowed_client_config() { + local cfg="$1" + local new_file="$2" + local enabled node pwd netip clientip serverip persist compress keepalive proto + + if [ $TUNNUM -lt $MAXTUNNUM ] + then + config_get_bool enabled "$cfg" enabled + config_get node "$cfg" node + config_get passwd "$cfg" passwd + config_get netip "$cfg" netip + config_get clientip "$cfg" clientip + config_get serverip "$cfg" serverip + config_get persist "$cfg" persist "yes" + config_get compress "$cfg" compress "lzo:9" + config_get keepalive "$cfg" keepalive "yes" + config_get proto "$cfg" proto "tcp" + + if [ $enabled -eq 1 ] + then + echo "node $node {" >> $new_file + echo " passwd $passwd;" >> $new_file + echo " type tun;" >> $new_file + echo " proto $proto;" >> $new_file + echo " device tun${TUNNUM};" >> $new_file + echo " persist $persist;" >> $new_file + echo " compress $compress;" >> $new_file + echo " keepalive $keepalive;" >> $new_file + echo " up {" >> $new_file + echo -e " ifconfig \"%% ${serverip} netmask 255.255.255.252 pointopoint ${clientip} mtu 1450\";" >> $new_file + echo -e " route \"add -net ${netip}/30 gw ${clientip}\";" >> $new_file + echo " };" >> $new_file + echo " down {" >> $new_file + echo " };" >> $new_file + echo "}" >> $new_file + echo " " >> $new_file + TUNNUM=$(( TUNNUM + 1 )) + fi + else + echo "## TOO MANY TUNNEL CONNECTIONS (${TUNNUM}) ##" >> $new_file + fi +} + +apply_uci_config() { + sh -c '. /lib/functions.sh; include /lib/config; uci_apply_defaults' +} + +start() { + apply_uci_config + config_load vtun + + # Remove the current config files + rm -f $SERVER_CONF + + config_foreach network_config network + config_foreach options_config options "$SERVER_CONF" + config_foreach allowed_client_config client "$SERVER_CONF" + + # START SERVER LISTENER + /usr/sbin/vtund -s -f $SERVER_CONF +} + +stop() { + # find the vtund SERVER process... --- FIX THIS + for x in `ps -w|grep -F 'vtund[s]:'|grep -v grep|tr -s ' '|cut -d' ' -f2` + do + s=`echo $s $x` + done + kill $s +} diff --git a/files/etc/mesh-release b/files/etc/mesh-release index 1388dd84..5595717a 100644 --- a/files/etc/mesh-release +++ b/files/etc/mesh-release @@ -1 +1 @@ -0.10.x +3.1.1TUNNEL diff --git a/files/usr/local/bin/vtun_up b/files/usr/local/bin/vtun_up new file mode 100644 index 00000000..2dd08109 --- /dev/null +++ b/files/usr/local/bin/vtun_up @@ -0,0 +1,128 @@ +#!/bin/sh +# AE6XE 2014-12-08 +# This script assumes a pre-existing OpenWRT-UCI netfilter table structure +# $1 = tun0 | tun1 | ... | tun9 +# $2 = up | down + +interface=$1 +action=$2 +is_olsrgw=`cat /etc/config.mesh/_setup|grep -i olsrd_gw|cut -d ' ' -f 3` +configmode=`uci -q -c /etc/local/uci/ get hsmmmesh.settings.config` +inf_count=`ifconfig | egrep "^tun[0-9]" | wc -l` +echo "Firewall rules for $interface $action" + +# Do nothing if node is not in mesh mode +if [ "$configmode" != "mesh" ] ; then exit 0; fi + +# Test for pre-existing firewall rules which use a wildcard and only need setup 1 time for multiple tunnel connections +if ( `iptables -L forwarding_vpn | egrep "^Chain forwarding_vpn \(.+ references\)" > /dev/null` ) then + rules_exist=1 +else + rules_exist=0 +fi + +# Do nothing on firewall if tunnels already (or still) exist--set up once for first and remove on last down +if [ $rules_exist -eq 0 -a "$action" = "up" ] ; then + echo "Adding vtun firewall rules..." + iptables -N forwarding_vpn + iptables -N input_vpn + iptables -N zone_vpn + iptables -N zone_vpn_ACCEPT + iptables -N zone_vpn_DROP + iptables -N zone_vpn_REJECT + iptables -N zone_vpn_forward + iptables -A forward -i tun+ -j zone_vpn_forward + iptables -A input -i tun+ -j zone_vpn + iptables -A output -j zone_vpn_ACCEPT + iptables -A zone_vpn -p icmp -m icmp --icmp-type 8 -j ACCEPT + iptables -A zone_vpn -p tcp -m tcp --dport 2222 -j ACCEPT + iptables -A zone_vpn -p tcp -m tcp --dport 8080 -j ACCEPT + iptables -A zone_vpn -p udp -m udp --dport 698 -j ACCEPT + iptables -A zone_vpn -p tcp -m tcp --dport 1978 -j ACCEPT + iptables -A zone_vpn -p tcp -m tcp --dport 23 -j ACCEPT + iptables -I zone_dtdlink_forward 1 -j zone_vpn_ACCEPT + if [ ! $is_olsrgw -eq 1 ] ; then + iptables -I zone_dtdlink_forward 1 -j zone_wan_REJECT + fi + iptables -I zone_lan_forward 1 -j zone_vpn_ACCEPT + iptables -I zone_wifi_forward 1 -j zone_vpn_ACCEPT + if [ ! $is_olsrgw -eq 1 ] ; then + iptables -I zone_wifi_forward 1 -j zone_wan_REJECT + fi + iptables -I zone_vpn_forward 1 -j zone_vpn_ACCEPT + iptables -I zone_vpn_forward -j zone_wan_REJECT + iptables -A zone_vpn -j input_vpn + iptables -A zone_vpn -j zone_vpn_ACCEPT + iptables -A zone_vpn_ACCEPT -o tun+ -j ACCEPT + iptables -A zone_vpn_ACCEPT -i tun+ -j ACCEPT + iptables -A zone_vpn_DROP -o tun+ -j DROP + iptables -A zone_vpn_DROP -i tun+ -j DROP + iptables -A zone_vpn_REJECT -o tun+ -j reject + iptables -A zone_vpn_REJECT -i tun+ -j reject + iptables -A zone_vpn_forward -j zone_dtdlink_ACCEPT + iptables -A zone_vpn_forward -j zone_lan_ACCEPT + iptables -A zone_vpn_forward -j zone_wifi_ACCEPT + iptables -A zone_vpn_forward -j forwarding_vpn +fi + +if [ $inf_count -eq 0 -a "$action" = "down" ] ; then + echo "Removing vtun firewall rules..." + iptables -D zone_vpn_forward -j forwarding_vpn + iptables -D zone_vpn_forward -j zone_wifi_ACCEPT + iptables -D zone_vpn_forward -j zone_lan_ACCEPT + iptables -D zone_vpn_forward -j zone_dtdlink_ACCEPT + iptables -D zone_vpn_REJECT -i tun+ -j reject + iptables -D zone_vpn_REJECT -o tun+ -j reject + iptables -D zone_vpn_DROP -i tun+ -j DROP + iptables -D zone_vpn_DROP -o tun+ -j DROP + iptables -D zone_vpn_ACCEPT -i tun+ -j ACCEPT + iptables -D zone_vpn_ACCEPT -o tun+ -j ACCEPT + iptables -D zone_vpn -j zone_vpn_ACCEPT + iptables -D zone_vpn -j input_vpn + iptables -D zone_vpn_forward -j zone_wan_REJECT + iptables -D zone_vpn_forward -j zone_vpn_ACCEPT + iptables -D zone_wifi_forward -j zone_vpn_ACCEPT + iptables -D zone_wifi_forward -j zone_wan_REJECT + iptables -D zone_lan_forward -j zone_vpn_ACCEPT + iptables -D zone_dtdlink_forward -j zone_vpn_ACCEPT + iptables -D zone_dtdlink_forward -j zone_wan_REJECT + iptables -D zone_vpn -p tcp -m tcp --dport 23 -j ACCEPT + iptables -D zone_vpn -p tcp -m tcp --dport 1978 -j ACCEPT + iptables -D zone_vpn -p udp -m udp --dport 698 -j ACCEPT + iptables -D zone_vpn -p tcp -m tcp --dport 8080 -j ACCEPT + iptables -D zone_vpn -p tcp -m tcp --dport 2222 -j ACCEPT + iptables -D zone_vpn -p icmp -m icmp --icmp-type 8 -j ACCEPT + iptables -D output -j zone_vpn_ACCEPT + iptables -D input -i tun+ -j zone_vpn + iptables -D forward -i tun+ -j zone_vpn_forward + iptables -X zone_vpn_REJECT + iptables -X zone_vpn_DROP + iptables -X zone_vpn_ACCEPT + iptables -X zone_vpn + iptables -X zone_vpn_forward + iptables -X input_vpn + iptables -X forwarding_vpn +fi + +if [ "$action" = "up" ] ; then + # Adding route policies for tunnel interface + if ( ! `ip rule list | egrep "^20020:.*$interface.*30" > /dev/null`) then + if [ -e /etc/config/dmz-mode ] ; then + ip rule add pref 20010 iif $interface lookup 29 # local interfaces + fi + ip rule add pref 20020 iif $interface lookup 30 # mesh + # ensure routing to internet is the local interface on this + # node and not forwarded to another gateway on the local mesh + # firewall rules above will always REJECT wan access comming across the tunnel + ip rule add pref 20090 iif $interface lookup main # local routes including wan + ip rule add pref 20099 iif $interface unreachable + fi +else + # Remove route policies for tunnel interface + ip rule del pref 20010 iif $interface lookup 29 + ip rule del pref 20020 iif $interface lookup 30 + ip rule del pref 20090 iif $interface lookup main + ip rule del pref 20099 iif $interface unreachable +fi + +exit 0; diff --git a/files/www/cgi-bin/tunfunc.pm b/files/www/cgi-bin/tunfunc.pm new file mode 100644 index 00000000..e9824f31 --- /dev/null +++ b/files/www/cgi-bin/tunfunc.pm @@ -0,0 +1,148 @@ +################################# +# get base network from config - CHANGE FOR UCI +################################# +sub get_server_network_address() +{ + my @list =(); + my $server_net=`uci get vtun.@network[0].start`; + + if($server_net ne "") + { + # to facilitate overrides (ie. moving the server to a new node) + # read the file into $mac + @list = split('\.', $server_net); + } + else + { + # or, calc based on eth0 mac address, then store it. + $mac=get_mac("eth0"); + @MACS=split(/:/, $mac); + push @list, "172"; + push @list, "31"; + push @list, hex @MACS[5]; + # strip off the high bits + push @list, ((hex @MACS[4]) << 2) & 255; + + $server_net=sprintf("%d.%d.%d.%d",@list[0],@list[1],@list[2],@list[3]); + system "uci add vtun network"; + system "uci set vtun.@network[0].start='${server_net}'"; + system "uci commit vtun"; + } + return @list; +} + +sub get_active_tun() +{ + my @active_tun; + foreach(`ps -w|grep vtun|grep ' tun '`) + { + @parts = $_ =~ /.*\:.*-(172-31-.*)\stun\stun.*/g;1; + @parts[0] =~ s/\-/\./g; + push(@active_tun,@parts[0]); + } + return @active_tun; +} + +# INPUT arg: Array of active tunnel IP's, IP of the tunnel network you are checking +sub is_tunnel_active() +{ + my ($n, @active_tun) = @_; + my $match=0; + foreach(@active_tun){ + #print "a=$_, n=$n\n"; + if($n eq $_) { + $match = 1; + last; + } + } + return $match; # the return value of the do block +} + +# Get hardware model/type +sub get_model() +{ + $model_full=`/usr/local/bin/get_model`; + if($model_full=~ m/ubiquiti.*/i) { + $model="UBNT"; + } else { + $model="LS"; + } +} + +########################## +# Add OLSRD interfaces - called when adding a new client connection +########################## +sub add_olsrd_interface() { + my ($tunnum) = @_; + # uci add_list olsrd.interface=vpn${tunnumber} + # uci commit vtundsrv + +#config Interface +# list interface 'vpn50 vpn51 vpn52 vpn53 vpn54 vpn55 vpn56 vpn57 vpn58 vpn59' +# option Ip4Broadcast 255.255.255.255 + +} + + +########################## +# Delete OLSRD interfaces - called when deleting a new client connection +########################## +sub del_olsrd_interface() { + my ($tunnum) = @_; + # uci delete_list olsrd.interface.vpn${tunnumber} + # uci commit vtundsrv + +#config Interface +# list interface 'vpn50 vpn51 vpn52 vpn53 vpn54 vpn55 vpn56 vpn57 vpn58 vpn59' +# option Ip4Broadcast 255.255.255.255 +} + +########################## +# Add network interfaces tun50 thru tun69 - called on install +########################## +sub add_network_interfaces() { + for ($tunnum = 50; $tunnum <= 69; $tunnum++) + { + system "uci set network.vpn${tunnum}=interface"; + system "uci set network.vpn${tunnum}.ifname='tun${tunnum}"; + system "uci set network.vpn${tunnum}.proto='none'"; + } + system "uci commit network"; +} + +########################## +# Delete OLSRD interfaces - called when deleting a new client connection +########################## +sub del_olsrd_interface() { + my ($tunnum) = @_; + # uci delete_list olsrd.interface.vpn${tunnumber} + # uci commit vtundsrv + # +} + +################################# +# Check Freespace on / filesystem +################################# +sub check_freespace() +{ + my $fs = `df / | grep -v '^Filesystem' | awk 'NF=6{print \$4}NF==5{print \$3}{}'`; + chomp $fs; + return $fs; +} + +########################## +# Config firewall to allow port 5525 on WAN interface +########################## +sub open_5525_on_wan() { + system "uci add firewall rule"; + system "uci set firewall.@rule[-1].src='wan'"; + system "uci set firewall.@rule[-1].dest_port='5525'"; + system "uci set firewall.@rule[-1].proto='tcp'"; + system "uci set firewall.@rule[-1].target='ACCEPT'"; + system "uci commit firewall" ;` +} + + + +#weird uhttpd/busybox error requires a 1 at the end of this file +1 \ No newline at end of file diff --git a/files/www/cgi-bin/ucifunc.pm b/files/www/cgi-bin/ucifunc.pm new file mode 100644 index 00000000..32c2654c --- /dev/null +++ b/files/www/cgi-bin/ucifunc.pm @@ -0,0 +1,42 @@ +### UCI Helpers START ### +sub uci_get_type_count() +{ + my ($config, $stype)=@_; + my $cmd=sprintf('uci show %s|egrep vtun\.\@%s.*=%s|wc -l',$config,$stype,$stype); + my $rc=`$cmd`; + chomp($rc); + return $rc; +} + +sub uci_get_indexed_item() +{ + my ($config,$stype,$index,$key)=@_; + my $cmd=sprintf('uci get %s.@%s[%s].%s',$config,$stype,$index,$key); + $e=`$cmd`; + chomp($e); + return $e; +} + +sub uci_set_indexed_option() +{ + my ($config,$stype,$index,$option,$val)=@_; + my $cmd=sprintf('uci set %s.@%s[%s].%s=%s',$config,$stype,$index,$option,$val); + $e=`$cmd`; + #return $cmd; + return $?; +} + +sub uci_delete_indexed_type() +{ + my ($config,$stype,$index)=@_; + my $cmd=sprintf('uci delete %s.@%s[%s]',$config,$stype,$index); + + $e=`$cmd`; + print $?; + return $?; +} +### UCI Helpers END ### + +#weird uhttpd/busybox error requires a 1 at the end of this file +1 + diff --git a/files/www/cgi-bin/vpn b/files/www/cgi-bin/vpn new file mode 100755 index 00000000..6a6977a6 --- /dev/null +++ b/files/www/cgi-bin/vpn @@ -0,0 +1,575 @@ +#!/usr/bin/perl +$debug = 0; +BEGIN {push @INC, '/www/cgi-bin'}; +use perlfunc; +use ucifunc; +use tunfunc; + +$VPNVER="1.0"; +$config = nvram_get("config"); +$node = nvram_get("node"); +$node = "NOCALL" if $node eq ""; +$unode = uc $node; # UPPER CASE NODENAME +$vpncfile = "/etc/vpnclients"; +$tmpdir = "/tmp/web/vpn"; +$tmpvtundsconf = "${tmpdir}/vtundsrv.conf.tmp"; +$tmpconnfile = "${tmpdir}/vpnclients"; +$tsfile = "/etc/tunnel.server"; +$tmptsfile = "${tmpdir}/tunnel.server.tmp"; + +read_postdata(); + +################# +# page checks +################# +if($parms{button_reboot}) +{ + system "/sbin/reboot"; +} + +if($parms{button_install}) +{ + &install_vtun(); +} + +&reboot_required() if($config eq "" or -e "/tmp/reboot-required"); +&vpn_setup_required() unless(-e "/usr/sbin/vtund" ); +&get_model(); +&get_active_tun(); + +################# +# If RESET or FIRST TIME, load clients/servers from file into parms --- CHANGE not needed? +################# +system "rm -rf $tmpdir" unless $parms{reload}; +system "mkdir -p $tmpdir" unless $parms{reload}; + +# if RESET, delete the tunnel.server network number file --- CHANGE UCI +if($parms{button_reset}) +{ + system "rm -rf $tsfile"; +} + +################# +# get vtun network address +################# +@netw = (); +@netw = &get_server_network_address(); +#&DEBUGEXIT(@netw[2]); + +################# +# If RESET or FIRST TIME, load clients/servers from file into parms +################# +if($parms{button_reset} or not $parms{reload}) +{ + # load clients from CONFIG FILE + &get_client_info(); + + $parms{server_net1}=@netw[2]; + $parms{server_net2}=@netw[3]; + + # initialize the "add" entries to clear them + foreach $var (qw(client_add_enable client_add_name client_add_pass)) + { + $parms{$var} = ""; + $parms{$var} = "0" if($var eq 'client_add_enable'); + } +} +else +{ + #&DEBUGEXIT($parms{client1_enable}); +} + + +################# +# load clients from FORM and validate +################# +for($i =1 , @list = (); $i <= $parms{client_num}; ++$i) { push @list, $i } +push @list, "_add"; +$client_num = 0; + +foreach $val (@list) +{ + foreach $var (qw(enable name pass)) + { + $varname = "client${val}_$var"; + $parms{$varname} = "0" if($val eq "enable" and $parms{$varname} eq ""); + $parms{$varname} = "" unless $parms{$varname}; + $parms{$varname} =~ s/^\s+//; + $parms{$varname} =~ s/\s+$//; + if($val ne "_add") + { + if($parms{$varname} eq "" and ($var eq "enable")) + { + $parms{$varname} = "0"; + } + } + eval sprintf("\$%s = \$parms{%s}", $var, $varname); + } + + + # Validate ADDed values + if($val eq "_add") + { + # skip any null values on add or save + next unless ($enable or $name or $pass) and ($parms{client_add} or $parms{button_save}); + } # no delete capabilities as net renumbering is not allowed + + + if($val eq "_add" and $parm{button_save}) + { + push @cli_err, "$val this client must be added or cleared out before saving changes"; + next; + } + + push @cli_err, "A client name is required" if($name eq ""); + push @cli_err, "A client password is required" if($pass eq ""); + + next if $val eq "_add" and @cli_err and $cli_err[-1] =~ /^$val /; + + # Commit the data for this client + ++$client_num; + + $parms{"client${client_num}_enable"} = $enable; + $parms{"client${client_num}_name"} = uc $name; + $parms{"client${client_num}_pass"} = $pass; + + # Clear out the ADD values + if($val eq "_add") + { + foreach $var (qw(net enable name pass)) + { + $parms{"client_add_${var}"} = ""; + } + } +} + +################# +# SAVE the clients into the TMP file --- CHANGE TO UCI +################# +system "rm -f $tmpconnfile"; +open(FILE, ">$tmpconnfile"); +for($i = 1; $i <= $client_num; $i++) +{ + printf FILE "%d|%s|%s\n", + $parms{"client${i}_enable"}, + $parms{"client${i}_name"}, + $parms{"client${i}_pass"} +} +close(FILE); + +################# +# SAVE the server network numbers into the TMP file --- CHANGE UCI +################# +#if(($parms{server_net1} ~~ [0..252]) and ($parms{server_net2} ~~ [0..252])) +#{ + system "rm -f $tmptsfile"; + open(FILE, ">$tmptsfile"); + printf FILE "%d.%d.%d.%d",172,31,$parms{server_net1},$parms{server_net2}; + close(FILE); + $netw[2]=$parms{server_net1}; + $netw[3]=$parms{server_net2}; +#} +#else +#{ +# push @cli_err, "The server net values must be between 0-254!"; +# $parms{server_net1}=$netw[2]; +# $parms{server_net2}=$netw[3]; +#} + + +$parms{client_num} = $client_num; + + +################# +# save configuration --- CHANGE UCI +################# +if($parms{button_save} and not (@cli_err or @serv_err)) +{ + # save the tunnel.server ip address to file + system "cp -f $tmptsfile $tsfile"; + system "cp -f $tmpconnfile $vpncfile"; + #&generate_vtundsrv_conf(); + + # uci commit vtundsrv + # ./vtundsrv stop + # ./vtundsrv start + + # RESTART VTUNDSRV /etc/init.d/vtundsrv restart + unless($debug == 3) + { + push(@errors,"problem with vtundsrv") if system "/etc/init.d/vtundsrv restart > /dev/null 2>&1"; + } +} + + +###################################################################################### +# generate the page +###################################################################################### +http_header() unless $debug == 2; +html_header("$node setup", 1); + +print "
\n"; +print "
\n" unless $debug == 2; +print "\n" if $debug == 2; +print "\n"; + +################# +# Navigation bar +################# +print "\n"; + +################# +# control buttons +################# +print "\n"; +push @hidden, ""; + +################# +# messages +################# +if(@cli_err) +{ + print "\n"; +} + +if($parms{button_save}) +{ + if(@cli_err) + { + print "\n"; + } + elsif(@errors) + { + print "\n"; + } + else + { + print "\n"; + } + + print "\n"; +} + +################# +# everything else +################# +if($config eq "mesh") +{ + #print "\n"; + #print "\n"; + #print "\n"; + + print "\n"; + + print "\n"; +} +print "
\n"; +navbar("vpn"); +print "
"; +print "Help"; +print "   \n"; +print " \n"; +print " \n"; +print " \n"; +print "
 
ERROR:
"; + foreach(@cli_err) { print "$_
" } + print "
Configuration NOT saved!
Configuration saved, however:
"; + foreach(@errors) { print "$_
" } + print "
Configuration saved and is now active.
 
** THIS PAGE IS NON-FUNCTIONAL AT THE MOMENT **
\n"; + + #print "

\n"; + &print_vpn_clients(); + print "

\n"; +print "

VPN v${VPNVER}

"; +push @hidden, ""; + +################# +# add hidden form fields +################# +foreach(@hidden) { print "$_\n" } + +################# +# close the form +################# +print "
\n"; +show_debug_info(); + +################# +# close the html +################# +print "\n"; +exit; + + +################## +# page subsections +################## + +###################################################### +# List the clients allowed to connect to this server # +###################################################### +sub print_vpn_clients() +{ + print ""; + + #print ""; + print "
"; + print "\n"; + print "\n"; + print "\n"; + + for($i = 1, @list = (); $i <= $parms{client_num}; ++$i) { push @list, $i }; + + push @list, "_add" unless($parms{client_num} > 9); + + $cnum=0; + foreach $val (@list) + { + foreach $var (qw(enable name pass)) + { + eval sprintf("\$%s = \$parms{client%s_%s}", $var, $val, $var); + } + + print "\n" if $val eq "_add" and scalar(@list) > 1; + print ""; + print ""; + + print ""; + + print ""; + + # handle rollover of netw[3] + if(@netw[3]+($cnum * 4) > 252) { + @netw[2]++; + $netw[3] = 0; + $net=0; + $cnum=0; + } else { + $net=$cnum; + } + + if($val eq "_add") { $lastnet=@netw[3]+(($net) * 4); } + else { $lastnet=@netw[3]+($net * 4); } + $fullnet=sprintf("%d.%d.%d.%d",@netw[0],@netw[1],@netw[2],$lastnet); + + print ""; + print ""; + print ""; + + print "" unless($val eq "_add"); + print "\n"; + + # display any errors + while(@cli_err and $cli_err[0] =~ /^$val /) + { + $err = shift @cli_err; + $err =~ s/^\S+ //; + print "\n"; + } + + #push @hidden, "" unless($val eq "_add"); + + print "\n"; + $cnum++; + } + print "
Virtual Tunnel Server Enabled?
Virtual Tunnel Server Network: "; + printf("%d.%d.",@netw[0],@netw[1]); + print ""; + print "."; + print ""; + print " (must be between 0 and 254)

Allow the following clients to connect to this server:
Enabled?ClientPwdNetActive Action
"; + + # Required to be first, so, if the checkbox is cleared, a value will still POST + print "" unless($val eq "_add"); + print "   $fullnet "; + #print "" if(@active_tun[$cnum]); + print "" if((&is_tunnel_active($name)) && ($val ne "_add")); + print "" if($val eq "_add"); + print "Email
$err
\n"; +} + + + +################################# +# generate the vtundsrv server file --- CHANGE FOR UCI +################################# +sub generate_vtundsrv_conf() +{ + # Start with the header + open MYFILE, ">${tmpvtundsconf }"; + print MYFILE &vtundsrv_conf_head; + + # loop over $vpncfile + $cnum=0; + foreach(`cat $vpncfile 2>/dev/null`) + { + next if /^\s*#/; ## ignore lines that start with '#' + next if /^\s*$/; ## ignore lines that start with '$' + chomp; + + @parts = split /\|/, $_; + + next unless scalar(@parts) == 3; + + $enable = @parts[0]; + $name = @parts[1]; + $pass = @parts[2]; + + unless($enable) + { + $cnum++; ## to make sure the tun and ip addresses remain constant + next; + } + + $net3=@netw[2]; + $net4=@netw[3]+($cnum*4); + $netnet=sprintf("%d.%d.%d.%d",@netw[0],@netw[1],$net3,$net4); + $netcli=sprintf("%d.%d.%d.%d",@netw[0],@netw[1],$net3,$net4+1); + $netserv=sprintf("%d.%d.%d.%d",@netw[0],@netw[1],$net3,$net4+2); + $clientname=sprintf("%s-%d-%d-%d-%d",$name,@netw[0],@netw[1],$net3,$net4); + + $tmpConnectionString=&vtundsrv_conf_client; + $tmpConnectionString =~ s/%CLIENTNAME%/$clientname/g; + $tmpConnectionString =~ s/%CLIENTPASS%/$pass/g; + $tmpConnectionString =~ s/%CLIENTNUMBER%/$cnum/g; + $tmpConnectionString =~ s/%NETNET%/$netnet/g; + $tmpConnectionString =~ s/%NETCLIENT%/$netcli/g; + $tmpConnectionString =~ s/%NETSERVER%/$netserv/g; + if($model eq "UBNT") { $tmpConnectionString =~ s/encrypt..yes/encrypt oldblowfish128ecb/g; } + + print MYFILE $tmpConnectionString; + $cnum++; + } + close MYFILE; + + # backup the original file + system "cp -f /etc/vtundsrv.conf /etc/vtundsrv.conf.bak> /dev/null 2>&1"; + system "cp -f $tmpvtundsconf /etc/vtundsrv.conf> /dev/null 2>&1"; +} + +################################# +# load client info from config file - CHANGE FOR UCI +################################# +sub get_client_info() +{ + $i=0; + foreach(`cat $vpncfile 2>/dev/null`) + { + next if /^\s*#/; ## ignore lines that start with '#' + next if /^\s*$/; ## ignore lines that start with '$' + chomp; + + @parts = split /\|/, $_; + next unless scalar(@parts) == 3; + ++$i; + + foreach $var (qw(enable name pass)) + { + $parms{"client${i}_$var"} = shift @parts; + $parms{"client${i}_$var"} = "0" if($parms{"client${i}_$var"} eq ""); + } + } + $parms{client_num} = $i; +} + +sub vpn_setup_required() +{ + http_header(); + html_header("$node setup", 1); + print "
"; + print ""; + ################# + # messages + ################# + if(@cli_err) + { + print "\n"; + } + print "\n"; + print "
\n"; + navbar("vpn"); + print "
ERROR:
"; + foreach(@cli_err) { print "$_
" } + print "

"; + print "VPN software needs to be installed.
"; + print "
\n"; + print ""; + print "
"; + print "
\n"; + exit; +} + +sub reboot_required() +{ + http_header(); + html_header("$node setup", 1); + print "
\n"; + print "
\n"; + navbar("vpn"); + print "

"; + if($config eq "") + { + print "This page is not available until the configuration has been set."; + } + else + { + print "The configuration has been changed.
This page will not be available until the node is rebooted.\n
"; + print "
\n"; + print ""; + print "
"; + } + print "
\n"; + exit; +} + +################################# +# Install VTUN Server Components/config +################################# +sub install_vtun() +{ + # check free disk space - get real values + $freespace=&check_freespace(); + + if($freespace < 600) + { + push @cli_err, "Insuffient free disk space!"; + } + else + { + # Update/Install VTUN + system "opkg update"; + system "opkg install kmod-tun zlib libopenssl liblzo vtun > /tmp/tunnel_install.log"; + + # Prep firewall + &open_5525_on_wan(); + + # add network interfaces + &add_network_interfaces(); + + # Reboot required + system "touch /tmp/reboot-required"; + } +} + + +sub DEBUGEXIT() +{ + my ($text) = @_; + http_header(); + html_header("$node setup", 1); + print "DEBUG-"; + print $text; + print ""; + exit; +} \ No newline at end of file diff --git a/files/www/cgi-bin/vpnc b/files/www/cgi-bin/vpnc new file mode 100755 index 00000000..03f2c60c --- /dev/null +++ b/files/www/cgi-bin/vpnc @@ -0,0 +1,449 @@ +#!/usr/bin/perl +$debug = 1; +BEGIN {push @INC, '/www/cgi-bin'}; +use perlfunc; +use ucifunc; +use tunfunc; + +$VPNVER="1.0"; +$config = nvram_get("config"); +$node = nvram_get("node"); +$node = "NOCALL" if $node eq ""; +$unode = uc $node; # UPPER CASE NODENAME +#$vpnconnfile = "/etc/vtun.connections"; +#$tmpdir = "/tmp/web/vpn"; +#$tmpvtundconf = "${tmpdir}/vtund.conf.tmp"; +#$tmpvtundservice = "${tmpdir}/vtund.service.tmp"; # contains connection rows +#$tmpvtund = "${tmpdir}/vtund.tmp"; +#$tmpconnfile = "${tmpdir}/vpnconnections"; + +&get_model(); + +read_postdata(); +@active_tun=&get_active_tun(); + +################# +# page checks +################# +&reboot_required() if($config eq "" or -e "/tmp/reboot-required"); +&vpn_setup_required() unless(-e "/usr/sbin/vtund" ); + +################# +# If RESET or FIRST TIME, load servers from file into parms +################# +if($parms{button_reset} or not $parms{reload}) +{ + # load connections from UCI + &get_connection_info(); + + # initialize the "add" entries to clear them + foreach $var (qw(conn_add_enabled conn_add_host conn_add_passwd conn_add_netip)) + { + $parms{$var} = ""; + $parms{$var} = "0" if($var eq 'conn_add_enabled'); + } +} +else +{ + #&DEBUGEXIT($parms{client1_enable}); +} + + +################# +# load connections from FORM and validate +################# +for($i =1 , @list = (); $i <= $parms{conn_num}; ++$i) { push @list, $i } +push @list, "_add"; +$conn_num = 0; + +foreach $val (@list) +{ + foreach $var (qw(enabled host passwd netip)) + { + $varname = "conn${val}_$var"; + $parms{$varname} = "0" if($val eq "enabled" and $parms{$varname} eq ""); + $parms{$varname} = "" unless $parms{$varname}; + $parms{$varname} =~ s/^\s+//; + $parms{$varname} =~ s/\s+$//; + if($val ne "_add") + { + if($parms{$varname} eq "" and ($var eq "enabled")) + { + $parms{$varname} = "0"; + } + } + eval sprintf("\$%s = \$parms{%s}", $var, $varname); + } + + + # Validate ADDed values + if($val eq "_add") { next unless ($enabled or $host or $passwd or $netip) and ($parms{conn_add} or $parms{button_save}) } + else { next if $parms{"conn${val}_del"} } + + if($val eq "_add" and $parm{button_save}) + { + push @conn_err, "$val this connection must be added or cleared out before saving changes"; + next; + } + + push @conn_err, "A connection server is required" if($host eq ""); + push @conn_err, "A connection password is required" if($passwd eq ""); + + next if $val eq "_add" and @cli_err and $cli_err[-1] =~ /^$val /; + + # Commit the data for this connection + ++$conn_num; + + $parms{"conn${conn_num}_enabled"} = $enabled; + $parms{"conn${conn_num}_host"} = $host; + $parms{"conn${conn_num}_passwd"} = $passwd; + $parms{"conn${conn_num}_netip"} = $netip; + + # Clear out the ADD values + if($val eq "_add") + { + foreach $var (qw(enabled host passwd netip)) + { + $parms{"conn_add_${var}"} = ""; + } + } +} + +################# +# SAVE the clients the UCI vtun file +################# +$parms{conn_num} = $conn_num; + +if($parms{button_save} and not (@conn_err or @serv_err)) +{ + # ADD/SET all server type entries + for($i=1; $i<=$conn_num; $i++) + { + foreach $var (qw(enabled host passwd netip)) + { + eval sprintf("\$val = \$parms{conn%s_%s}",$i,$var); + $idx=$i*(-1); + push(@errors,"Problem adding server entry into config file") if &uci_set_indexed_option("vtun","server",$idx,$var,$val); + } + # TODO: calculate clientip and serverip + # + # TODO: uci_set_indexed_option("vtun","server",-1,"clientip",$clientip); + # TODO: uci_set_indexed_option("vtun","server",-1,"clientip",$serverip); + # TODO: uci_set_indexed_option("vtun","server",-1,"node",$nodename) + } + + push(@errors,"Problem committing server entry into config file") if system "uci commit vtun > /dev/null 2>&1"; + + # COPY /etc/config/vtun to /etc/config.mesh/vtun (to workaround node-setup script issues) + system "cp /etc/config/vtun /etc/config.mesh/vtun"; + + # STOP vtun clients + system "/etc/init.d/vtund stop > /dev/null 2>&1"; + + # START VTUND /etc/init.d/vtund start + unless($debug == 3) + { + push(@errors,"Problem starting vtund") if system "/etc/init.d/vtund start > /dev/null 2>&1"; + } +} + + +###################################################################################### +# generate the page +###################################################################################### +http_header() unless $debug == 2; +html_header("$node setup", 1); + +print "
\n"; +print "
\n" unless $debug == 2; +print "\n" if $debug == 2; +print "\n"; + +################# +# Navigation bar +################# +print "\n"; + +################# +# control buttons +################# +print "\n"; +push @hidden, ""; + +################# +# messages +################# +if(@cli_err) +{ + print "\n"; +} + +if($parms{button_save}) +{ + if(@cli_err) + { + print "\n"; + } + elsif(@errors) + { + print "\n"; + } + else + { + print "\n"; + } + + print "\n"; +} + +################# +# everything else +################# +if($config eq "mesh") +{ + print "\n"; + + print "\n"; +} +print "
\n"; +navbar("vpnc"); +print "
"; +print "Help"; +print "   \n"; +print " \n"; +print " \n"; +print " \n"; +print "
 
ERROR:
"; + foreach(@conn_err) { print "$_
" } + print "
Configuration NOT saved!
Configuration saved, however:
"; + foreach(@errors) { print "$_
" } + print "
Configuration saved and is now active.
 
\n"; + &print_vpn_connections(); + print "

\n"; +print "

VPN v${VPNVER}

"; +push @hidden, ""; + +################# +# add hidden form fields +################# +foreach(@hidden) { print "$_\n" } + +################# +# close the form +################# +print "
\n"; +show_debug_info(); + +################# +# close the html +################# +print "\n"; +exit; + + +################## +# page subsections +################## + + +###################################################### +# List the connections to be made from this client +###################################################### +sub print_vpn_connections() +{ + print ""; + print ""; + print "\n"; + print "\n"; + + for($i = 1, @list = (); $i <= $parms{conn_num}; ++$i) { push @list, $i }; + + push @list, "_add" unless($parms{conn_num} > 9); + + $cnum=0; + foreach $val (@list) + { + foreach $var (qw(enabled host passwd netip)) + { + eval sprintf("\$%s = \$parms{conn%s_%s}", $var, $val, $var); + } + + print "\n" if $val eq "_add" and scalar(@list) > 1; + print ""; + print ""; + + print ""; + + print ""; + + print ""; + + #if($val eq "_add") { print @netw[3]+(($net) * 4); } + #else { print @netw[3]+($net * 4); } + + #print @netw[3]+($net * 4) unless $val eq "_add"; + print ""; + print ""; + print "\n"; + + # display any errors + while(@conn_err and $conn_err[0] =~ /^$val /) + { + $err = shift @conn_err; + $err =~ s/^\S+ //; + print "\n"; + } + + #push @hidden, "" unless($val eq "_add"); + + print "\n"; + $cnum++; + } + print "
Connect this node to the following servers:

Enabled?ServerPwdNetworkActive Action
"; + + # Required to be first, so, if the checkbox is cleared, a value will still POST + print "" unless($val eq "_add"); + print "     "; + #print "" if(@active_tun[$cnum]); + print "" if((&is_tunnel_active($netip, @active_tun)) && ($val ne "_add")); + print " "; + + print "
$err
\n"; +} + + +################################# +# generate the UCI file +################################# +sub build_uci() +{ + + # loop over each connection + #$cnum=0; + foreach(`cat $vpnconnfile 2>/dev/null`) + { + next if /^\s*#/; ## ignore lines that start with '#' + next if /^\s*$/; ## ignore lines that start with '$' + chomp; + + @parts = split /\|/, $_; + + next unless scalar(@parts) == 4; + + $enable = @parts[0]; + $server = @parts[1]; + $pass = @parts[2]; + $net = @parts[3]; + + @netw=split /\./, $net; + + unless($enable) + { + # $cnum++; ## to make sure the tun and ip addresses remain constant + next; + } + $clientname=sprintf("%s-%d-%d-%d-%d",$unode,@netw[0],@netw[1],@netw[2],@netw[3]); + $net3=@netw[2]; + #$net4=@netw[3]+($cnum*4); + $net4=@netw[3]; + $netnet=sprintf("%d.%d.%d.%d",@netw[0],@netw[1],$net3,$net4); + $netcli=sprintf("%d.%d.%d.%d",@netw[0],@netw[1],$net3,$net4+1); + $netserv=sprintf("%d.%d.%d.%d",@netw[0],@netw[1],$net3,$net4+2); + + # uci set vtun.@server[-1].host + # uci set vtun.@server[-1].node + # uci set vtun.@server[-1].passwd + # uci set vtun.@server[-1].netip + # uci commit vtun + + $cnum++; + } +} + +################################# +# load info from UCI +################################# +sub get_connection_info() +{ + my $x; + + # how many connections + my $connection_count=&uci_get_type_count("vtun","server"); + + for (my $i=1; $i<=$connection_count; $i++) { + + foreach $var (qw(enabled host passwd netip)) + { + $x=&uci_get_indexed_item("vtun","server",$i-1,$var); + $parms{"conn${i}_${var}"}=$x; + #eval sprintf("\$%s = \$parms{conn%s_%s}", $var, $val, $var); + } + } + $parms{conn_num} = $connection_count; +} + + + +# VPN software is not installed +sub vpn_setup_required() +{ + http_header(); + html_header("$node setup", 1); + print "
\n"; + print "
\n"; + navbar("vpn"); + print "

"; + print "VPN software needs to be installed."; + #print ""; + print "
\n"; + exit; +} + +# A reboot is required +sub reboot_required() +{ + http_header(); + html_header("$node setup", 1); + print "
\n"; + print "
\n"; + navbar("vpn"); + print "

"; + if($config eq "") + { + print "This page is not available until the configuration has been set."; + } + else + { + print "The configuration has been changed.
This page will not be available until the node is rebooted.\n"; + } + print "
\n"; + exit; +} + +sub DEBUGEXIT() +{ + my ($text) = @_; + http_header(); + html_header("$node setup", 1); + print "DEBUG["; + print $text; + print "]"; + exit; +} \ No newline at end of file