From 5d6e4dd05cc19d2606c8ebc90a89511352affd5b Mon Sep 17 00:00:00 2001 From: ana Date: Fri, 12 Jan 2007 22:48:39 +0000 Subject: [PATCH] Added ipsec.tcl Bug found by: Submitted by: Requested by: Reviewed by: Approved by: Obtained from: --- ipsec.tcl | 1025 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1025 insertions(+) create mode 100755 ipsec.tcl diff --git a/ipsec.tcl b/ipsec.tcl new file mode 100755 index 0000000..956f395 --- /dev/null +++ b/ipsec.tcl @@ -0,0 +1,1025 @@ +# +# Copyright 2004, 2005 University of Zagreb, Croatia. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of Zagreb, +# Croatia and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# This work was supported in part by the Croatian Ministry of Science +# and Technology through the research contract #IP-2003-143. +# + + +#****f* ipsec.tcl/editIpsecCfg +# NAME +# editIpsecCfg -- change or delete ipsec-config +# SYNOPSIS +# editIpsecCfg $w $node $deleteid $edit +# FUNCTION +# Change (if $edit == 1) or delete (if $edit == 0) +# particular ipsec-config defined by ipsec-config-id. +# INPUTS +# * w -- ipsec config window +# * node -- node +# * deleteid -- ipsec-config-id that determines +# which ipsec-config to delete +# * edit -- If $edit is set to "1", selected ipsec-config +# will be just edited. If $edit is set to "0", selected +# ipsec-config will be deleted. +#**** + +proc editIpsecCfg { w node deleteid edit } { + + global viewid + set ipsecCfgList [getIpsecConfig $node] + set i 0 + foreach element $ipsecCfgList { + set cid [lindex [lsearch -inline $element "ipsec-config-id *"] 1] + if { $deleteid == $cid } { + set ipsecCfgList [lreplace $ipsecCfgList $i $i] + } + incr i + } + + if { $edit == "1" } { + set add "0" + set ipsecCfg [ipsecConfigApply $w $node $add] + set newid [getConfig $ipsecCfg "ipsec-config-id"] + set viewid $newid + lappend ipsecCfgList $ipsecCfg + } + + removeIpsecConfig $node + foreach ipsecCfg $ipsecCfgList { + setIpsecConfig $node $ipsecCfg + } + + if { $edit != "1" } { + destroy $w + set delete "1" + } else { + set delete "0" + } + set view "1" + viewIpsecCfg $node $delete $view + + return +} + +#****f* ipsec.tcl/showIpsecErrors +# NAME +# showIpsecErrors -- show window with errors +# related to ipsec-config information +# SYNOPSIS +# showIpsecErrors $str +# FUNCTION +# Forms window with information about error made when +# manipulating ipsec-config information. +# INPUTS +# * str -- information about ipsec error that will be +# written in the error window. +#**** + +proc showIpsecErrors { str } { + global viewid + + set error "" + #foreach element $str { + # if { $element != "" } { + # append error $element "\n" + # } + #} + set error $str + + set w .cfgeditor + catch {destroy $w} + toplevel $w -takefocus 1 + #wm transient $w . + grab $w + catch {unset viewid} + frame $w.noentry -borderwidth 4 + label $w.noentry.label -text $error + pack $w.noentry.label -side left -anchor w + pack $w.noentry -side top -anchor w + + frame $w.noentrybuttons + pack $w.noentrybuttons -side bottom + button $w.noentrybuttons.close -text Close \ + -command "destroy $w" + pack $w.noentrybuttons.close -side left + +} + +#****f* ipsec.tcl/viewIpsecCfg +# NAME +# viewIpsecCfg -- form ipsec configuration window +# SYNOPSIS +# viewIpsecCfg $node $delete $view +# FUNCTION +# Form the ipsec configuration window, either for adding +# new ipsec-config structure or for editing existing +# ipsec-config structures. +# INPUTS +# * node -- node +# * delete -- If delete is "1", that means that viewIpsecCfg +# has been invoked after deleting ipsec-config with +# defined ipsec-config-id (determined by the global +# variable viewid). In that case, tk_optionmenu variable +# will be set to show the first element of the ipsecCfgList. +# If delete is "0", viewIpsecCfg has been invoked just to +# show existing ipsec-configs. +# * view -- If $view is set to "0", viewIpsecCfg is used to add new +# ipsec-config item. If view is set to "1" viewIpsecCfg is used to +# edit ipsec-config items. +#**** + +proc viewIpsecCfg { node delete view } { + + set idlist {} + global viewid + set ipsecCfgList [getIpsecConfig $node] + set len [llength $ipsecCfgList] + foreach ipsecCfg $ipsecCfgList { + set id [lindex [lsearch -inline $ipsecCfg "ipsec-config-id *"] 1] + lappend idlist $id + } + if { $delete == "1" } { + set viewid [lindex $idlist 0] + } + if { $view == "0" } { + catch {unset viewid} + } + + set ipsecCfg "" + + if { $view == "1" && $idlist == {} } { + + set error "There are no ipsec-config entries with specified ipsec-config-id." + showIpsecErrors $error + + } else { + + set w .cfgeditor + catch {destroy $w} + toplevel $w -takefocus 1 + #wm transient $w . + grab $w + wm title $w "Node $node" + wm iconname $w "$node" + + if { $view == "1" } { + frame $w.view -borderwidth 4 + label $w.view.label -text "View ipsec-config(s):" + pack $w.view.label -side left -anchor w + eval {tk_optionMenu $w.view.viewid viewid} $idlist + pack $w.view.label $w.view.viewid \ + -side left -anchor w + pack $w.view -side top -anchor w + set delete "0" + button $w.view.id -text View \ + -command "viewIpsecCfg $node $delete $view" + pack $w.view.id -side right + + foreach element $ipsecCfgList { + set cid [lindex [lsearch -inline $element "ipsec-config-id *"] 1] + if { $viewid == $cid } { + set ipsecCfg $element + } + } + } + + # + # ipsec-config name + # + frame $w.id -borderwidth 4 + label $w.id.label -text "ipsec-config id:" + pack $w.id.label -side left -anchor w + entry $w.id.text -bg white -width 30 + if { $ipsecCfg != "" } { + set id [ getConfig $ipsecCfg "ipsec-config-id"] + } else { + set id "" + } + $w.id.text insert end $id + pack $w.id.text $w.id.label -side left -padx 4 -pady 0 + pack $w.id -side top -anchor w + + # SAD database: + labelframe $w.sad -padx 4 -pady 4 + frame $w.sad.ftop -borderwidth 4 + label $w.sad.ftop.label -text "SAD database (Security Associations)" + pack $w.sad.ftop.label -side right + pack $w.sad.ftop -side top -anchor w + + # + # Source SA address + # + frame $w.sad.sourceSA -borderwidth 4 + label $w.sad.sourceSA.label -text "Src SA address:" + pack $w.sad.sourceSA.label -side left -anchor w + entry $w.sad.sourceSA.source -bg white -width 30 + if { $ipsecCfg != "" } { + set sourceSA [ getConfig $ipsecCfg "SA-source-address"] + } else { + set sourceSA "" + } + $w.sad.sourceSA.source insert end $sourceSA + pack $w.sad.sourceSA.source $w.sad.sourceSA.label \ + -side left -padx 4 -pady 0 + pack $w.sad.sourceSA -side top -anchor w + + # + # Destination SA address + # + frame $w.sad.destSA -borderwidth 4 + label $w.sad.destSA.label -text "Dst SA address:" + pack $w.sad.destSA.label -side left -anchor w + entry $w.sad.destSA.dest -bg white -width 30 + if { $ipsecCfg != {} } { + set destSA [ getConfig $ipsecCfg "SA-destination-address"] + } else { + set destSA "" + } + $w.sad.destSA.dest insert end $destSA + pack $w.sad.destSA.dest $w.sad.destSA.label \ + -side left -padx 4 -pady 0 + pack $w.sad.destSA -side top -anchor w + + # + # Security Paramters Index (SPI), 16 bit number + # (Both SAs and SPs exist in pairs: we need inbound + # and outbound SPI.) + # + frame $w.sad.spi -borderwidth 4 + label $w.sad.spi.inboundl -text "Inbound SPI:" + pack $w.sad.spi.inboundl -side left -anchor w + set inboundspi "" + if { $ipsecCfg != {} } { + set inboundspi [ getConfig $ipsecCfg "inbound-spi"] + } else { + set inboundspi "" + } + spinbox $w.sad.spi.inboundv -bg white -width 10 \ + -validate focus -invcmd "focusAndFlash %W" + $w.sad.spi.inboundv insert 0 $inboundspi + $w.sad.spi.inboundv configure \ + -from 1 -to 65535 -increment 1 \ + -vcmd {checkIntRange %P 1 65535} + pack $w.sad.spi.inboundl $w.sad.spi.inboundv \ + -side left -anchor w + + # Outbound SPI: + label $w.sad.spi.outboundl -text "Outbound SPI:" + pack $w.sad.spi.outboundl -side left -anchor w + if { $ipsecCfg != {} } { + set outboundspi [ getConfig $ipsecCfg "outbound-spi"] + } else { + set outboundspi "" + } + spinbox $w.sad.spi.outboundv -bg white -width 10 \ + -validate focus -invcmd "focusAndFlash %W" + $w.sad.spi.outboundv insert 0 $outboundspi + $w.sad.spi.outboundv configure \ + -from 2 -to 65535 -increment 1 \ + -vcmd {checkIntRange %P 2 65535 } + pack $w.sad.spi.outboundl $w.sad.spi.outboundv \ + -side left -anchor w + pack $w.sad.spi -side top -anchor w + + # + # IPsec algorithm (ESP or AH) + # + frame $w.sad.ipsecalg -borderwidth 4 + label $w.sad.ipsecalg.label -text "IPsec algorithm:" + pack $w.sad.ipsecalg.label -side left -anchor w + global ipsecalg + if { $ipsecCfg != {} } { + set ipsecalg [ getConfig $ipsecCfg "ipsec-algorithm"] + } else { + set ipsecalg esp + } + # TODO: Add ESP with authenticated payload + tk_optionMenu $w.sad.ipsecalg.alg ipsecalg esp ah + pack $w.sad.ipsecalg.label $w.sad.ipsecalg.alg \ + -side left -anchor w + + # IP compression: + label $w.sad.ipsecalg.ipcomp -text "IPcomp:" + pack $w.sad.ipsecalg.ipcomp -side left -anchor w + global ipcomp + if { $ipsecCfg != {} } { + set ipcomp [ getConfig $ipsecCfg "IPcomp-algorithm"] + } else { + set ipcomp no + } + radiobutton $w.sad.ipsecalg.ipcompyes -text "yes" \ + -variable ipcomp -value yes + radiobutton $w.sad.ipsecalg.ipcompno -text "no" \ + -variable ipcomp -value no + pack $w.sad.ipsecalg.ipcompyes -side top -anchor w + pack $w.sad.ipsecalg.ipcompno -side bottom -anchor w + pack $w.sad.ipsecalg.ipcomp \ + $w.sad.ipsecalg.ipcompyes $w.sad.ipsecalg.ipcompno \ + -side left -anchor w + pack $w.sad.ipsecalg -side top -anchor w + + # + # Crypto algorithm for ESP / AH (rfc4305) + # For ESP: des, 3des, 3des-cbc, aes-cbc, aes-ctr, null + # For AH: hmac-sha1-96, aes-xcbc-mac-96, null + # + frame $w.sad.cryptoalg -borderwidth 4 + label $w.sad.cryptoalg.label -text "Crypto algorithm:" + pack $w.sad.cryptoalg.label -side left -anchor w + global cryptoalgesp cryptoalgah + if { $ipsecCfg != {} } { + set crytoalgesp [ getConfig $ipsecCfg "esp-crypto-algorithm"] + set crytoalgah [ getConfig $ipsecCfg "ah-crypto-algorithm"] + } else { + set cryptoalgesp 3des-cbc + set cryptoalgah hmac-sha2-256 + } + tk_optionMenu $w.sad.cryptoalg.esp cryptoalgesp des-cbc 3des-cbc \ + simple blowfish-cbc cast128-cbc rijndael-cbc + tk_optionMenu $w.sad.cryptoalg.ah cryptoalgah hmac-md5 hmac-sha1 \ + keyed-md5 keyed-sha1 hmac-sha2-256 hmac-sha2-384 hmac-sha2-512 \ + null + pack $w.sad.cryptoalg.label $w.sad.cryptoalg.esp $w.sad.cryptoalg.ah \ + -side left -anchor w + pack $w.sad.cryptoalg -side top -anchor w + + # Shared secret for key derivation + # + frame $w.sad.psk -borderwidth 4 + label $w.sad.psk.label -text "Shared secret:" + entry $w.sad.psk.text -bg white -width 30 + if { $ipsecCfg != {} } { + set psk [ getConfig $ipsecCfg "shared-secret"] + } else { + set psk "" + } + $w.sad.psk.text insert end $psk + pack $w.sad.psk.text $w.sad.psk.label -side right -padx 4 -pady 0 + pack $w.sad.psk -side top -anchor w + pack $w.sad -side top -anchor w -fill both + + # + # SPD database: + # + labelframe $w.spd -padx 4 -pady 4 + frame $w.spd.spddb -borderwidth 4 + label $w.spd.spddb.label -text "SPD database (Security Policies)" + pack $w.spd.spddb.label -side right + pack $w.spd.spddb -side top -anchor w + + # + # Source SP address + # + frame $w.spd.sourceSP -borderwidth 4 + label $w.spd.sourceSP.label -text "Src SP address:" + entry $w.spd.sourceSP.source -bg white -width 30 + if { $ipsecCfg != "" } { + set sourceSP [ getConfig $ipsecCfg "SP-source-address"] + } else { + set sourceSP "" + } + $w.spd.sourceSP.source insert end $sourceSP + pack $w.spd.sourceSP.source $w.spd.sourceSP.label \ + -side right -padx 4 -pady 0 + pack $w.spd.sourceSP -side top -anchor w + + # + # Destination SP address + # + frame $w.spd.destSP -borderwidth 4 + label $w.spd.destSP.label -text "Dst SP address:" + entry $w.spd.destSP.dest -bg white -width 30 + if { $ipsecCfg != "" } { + set destSP [ getConfig $ipsecCfg "SP-destination-address"] + } else { + set destSP "" + } + $w.spd.destSP.dest insert end $destSP + pack $w.spd.destSP.dest $w.spd.destSP.label -side right -padx 4 -pady 0 + pack $w.spd.destSP -side top -anchor w + + # + # Source SGW address + # + frame $w.spd.sourcesgw -borderwidth 4 + label $w.spd.sourcesgw.label -text "Src SGW address:" + entry $w.spd.sourcesgw.source -bg white -width 30 + if { $ipsecCfg != "" } { + set sourcesgw [ getConfig $ipsecCfg "source-SGW-address"] + } else { + set sourcesgw "" + } + $w.spd.sourcesgw.source insert end $sourcesgw + pack $w.spd.sourcesgw.source $w.spd.sourcesgw.label \ + -side right -padx 4 -pady 0 + pack $w.spd.sourcesgw -side top -anchor w + + # + # Source SGW address + # + frame $w.spd.destsgw -borderwidth 4 + label $w.spd.destsgw.label -text "Dst SGW address:" + entry $w.spd.destsgw.source -bg white -width 30 + if { $ipsecCfg != "" } { + set destsgw [ getConfig $ipsecCfg "destination-SGW-address"] + } else { + set destsgw "" + } + $w.spd.destsgw.source insert end $destsgw + pack $w.spd.destsgw.source $w.spd.destsgw.label \ + -side right -padx 4 -pady 0 + pack $w.spd.destsgw -side top -anchor w + + # + # Traffic for protection: + # + frame $w.spd.traffic -borderwidth 4 + label $w.spd.traffic.label -text "Traffic:" + pack $w.spd.traffic.label -side left -anchor w + global traffic + if { $ipsecCfg != {} } { + set traffic [ getConfig $ipsecCfg "traffic-to-process"] + } else { + set traffic icmp + } + tk_optionMenu $w.spd.traffic.value traffic icmp tcp udp any + pack $w.spd.traffic.label $w.spd.traffic.value -side left -anchor w + + # + # Action (ipsec, discrad, bypass, none, entrust): + # + label $w.spd.traffic.action -text "Action:" + pack $w.spd.traffic.action -side left -anchor w + global action + if { $ipsecCfg != {} } { + set action [ getConfig $ipsecCfg "processing-action"] + } else { + set action ipsec + } + tk_optionMenu $w.spd.traffic.actionv action ipsec discard bypass + pack $w.spd.traffic.label $w.spd.traffic.value \ + $w.spd.traffic.action $w.spd.traffic.actionv \ + -side left -anchor w + + # + # Processing level: + # require, default, use + # + label $w.spd.traffic.level -text "Level:" + pack $w.spd.traffic.level -side left -anchor w + global level + if { $ipsecCfg != {} } { + set level [ getConfig $ipsecCfg "processing-level"] + } else { + set level require + } + tk_optionMenu $w.spd.traffic.levelv level require default use + pack $w.spd.traffic.label $w.spd.traffic.value \ + $w.spd.traffic.action $w.spd.traffic.actionv \ + $w.spd.traffic.level $w.spd.traffic.levelv \ + -side left -anchor w + pack $w.spd.traffic -side top -anchor w + + # + # SP ipsec algorithm (ESP or AH): + # + frame $w.spd.algandmode -borderwidth 4 + label $w.spd.algandmode.alg -text "IPsec algorithm:" + pack $w.spd.algandmode.alg -side left -anchor w + global spipsecalg + if { $ipsecCfg != {} } { + set spipsecalg [ getConfig $ipsecCfg "SP-ipsec-algorithm"] + } else { + set spipsecalg esp + } + radiobutton $w.spd.algandmode.esp -text "esp" \ + -variable spipsecalg -value esp + radiobutton $w.spd.algandmode.ah -text "ah" \ + -variable spipsecalg -value ah + pack $w.spd.algandmode.esp -side left -anchor w + pack $w.spd.algandmode.ah -side left -anchor w + + # + # Mode: + # transport + # tunnel (TODO) + # BEET (not yet supported in FreeBSD) + # + label $w.spd.algandmode.mode -text "Mode:" + pack $w.spd.algandmode.mode -side left -anchor w + global mode + if { $ipsecCfg != {} } { + set mode [ getConfig $ipsecCfg "ipsec-mode"] + } else { + set mode transport + } + radiobutton $w.spd.algandmode.transport -text "transport" \ + -variable mode -value transport + radiobutton $w.spd.algandmode.tunnel -text "tunnel" \ + -variable mode -value tunnel + pack $w.spd.algandmode.transport -side top -anchor w + pack $w.spd.algandmode.tunnel -side bottom -anchor w + pack $w.spd.algandmode -side top -anchor w + pack $w.spd -side top -anchor w -fill both + + # + # Buttons + # + frame $w.buttons + pack $w.buttons -side bottom + button $w.buttons.close -text Close -command "destroy $w" + if { $view == "1" } { + set edit "1" + button $w.buttons.delete -text Delete \ + -command "deleteIpsecCfg $w $node $viewid $edit" + button $w.buttons.apply -text Apply \ + -command "editIpsecCfg $w $node $viewid $edit" + pack $w.buttons.delete $w.buttons.close $w.buttons.apply -side left + } else { + set add "1" + button $w.buttons.apply -text "Apply" \ + -command "ipsecConfigApply $w $node $add" + pack $w.buttons.apply $w.buttons.close -side left + } + + } + + return +} + +#****f* ipsec.tcl/deleteIpsecCfg +# NAME +# deleteIpsecCfg -- invoke editIpsecCfg to delete +# ipsec-config item defined with ipsec-config-id +# viewid. +# SYNOPSIS +# deleteIpsecCfg $w $node $viewid $edit +# FUNCTION +# Invoke editIpsecCfg to delete defined ipsec-config. +# When deleting ipsec-config, $edit has to be set to "0". +# INPUTS +# * w -- ipsec configuration window +# * node -- node +# * viewid -- current ipsec-config-id from the +# tk_optionmenu. viewIpsecCfg always shows the +# ipsec-config determined by the global variable viewid. +# * edit -- if edit is set to "0", editIpsecCfg will delete +# ipsec-config defined by the ipsec-config-id viewid. +#**** + +proc deleteIpsecCfg { w node viewid edit } { + set edit "0" + editIpsecCfg $w $node $viewid $edit + return +} + +#****f* ipsec.tcl/ipsecConfigApply +# NAME +# ipsecConfigApply -- read ipsec configuration from +# the ipsec configuration window. Check the +# ipsec configuration. +# SYNOPSIS +# ipsecConfigApply $w $node $add +# FUNCTION +# Read ipsec configuration from the ipsec configuration +# window. Check the ipsec configuration by invoking +# checkIpsecCfg. +# INPUTS +# * w -- ipsec configuration window +# * node -- node +# * add -- If add is set to "1", ipsecConfigApply has +# been invoked after adding new ipsec-config element. +# If add is set to "0", ipsecConfigApply has been +# invoked when editing ipsec configuration. +# RESULT +# * ipsecCfg -- new ipsec-config structure +#**** + +proc ipsecConfigApply { w node add } { + global changed + global ipsecalg spipsecalg mode ipcomp + global cryptoalgesp cryptoalgah action traffic level + set ipsecCfg "" + set error "" + + set id [$w.id.text get] + set sourceSA [$w.sad.sourceSA.source get] + set destSA [$w.sad.destSA.dest get] + set inboundspi [$w.sad.spi.inboundv get] + set outboundspi [$w.sad.spi.outboundv get] + set psk [$w.sad.psk.text get] + set sourceSP [$w.spd.sourceSP.source get] + set destSP [$w.spd.destSP.dest get] + set sourcesgw [$w.spd.sourcesgw.source get] + set destsgw [$w.spd.destsgw.source get] + + if { $add == "1" } { + set valid [checkIpsecCfg $node "ipsec-config-id" $id] + if { $valid == "0" } { + destroy $w + set error "Choose another ipsec-config-id." + showIpsecErrors $error + return "" + } + } + + set ipsecCfg [setConfig $ipsecCfg $id "ipsec-config-id"] + set ipsecCfg [setConfig $ipsecCfg $sourceSA "SA-source-address"] + set ipsecCfg [setConfig $ipsecCfg $destSA "SA-destination-address"] + set ipsecCfg [setConfig $ipsecCfg $ipsecalg "ipsec-algorithm"] + set ipsecCfg [setConfig $ipsecCfg $ipcomp "IPcomp-algorithm"] + set ipsecCfg [setConfig $ipsecCfg $inboundspi "inbound-spi"] + set ipsecCfg [setConfig $ipsecCfg $outboundspi "outbound-spi"] + set ipsecCfg [setConfig $ipsecCfg $cryptoalgesp "esp-crypto-algorithm"] + set ipsecCfg [setConfig $ipsecCfg $cryptoalgah "ah-crypto-algorithm"] + set ipsecCfg [setConfig $ipsecCfg $psk "shared-secret"] + set ipsecCfg [setConfig $ipsecCfg $sourceSP "SP-source-address"] + set ipsecCfg [setConfig $ipsecCfg $destSP "SP-destination-address"] + set ipsecCfg [setConfig $ipsecCfg $sourcesgw "source-SGW-address"] + set ipsecCfg [setConfig $ipsecCfg $destsgw "destination-SGW-address"] + set ipsecCfg [setConfig $ipsecCfg $traffic "traffic-to-process"] + set ipsecCfg [setConfig $ipsecCfg $action "processing-action"] + set ipsecCfg [setConfig $ipsecCfg $spipsecalg "SP-ipsec-algorithm"] + set ipsecCfg [setConfig $ipsecCfg $mode "ipsec-mode"] + set ipsecCfg [setConfig $ipsecCfg $level "processing-level"] + + setIpsecConfig $node $ipsecCfg + destroy $w + return $ipsecCfg +} + +#****f* ipsec.tcl/checkIpsecCfg +# NAME +# checkIpsecCfg -- Check if there are errors in ipsec +# configuration input fields in ipsec configuration +# window. +# SYNOPSIS +# checkIpsecCfg $node $strd $str +# FUNCTION +# checkIpsecCfg will be incoked while doing ipsecConfigApply +# to check new inputs in the ipsec configuration window. +# INPUTS +# * node -- node +# * strd -- string description, that is i.e. "ipsec-config-id", +# "SA-source-address", etc. +# * str -- string, that is value related to strd. +# RESULT +# * valid -- valid is set to 0, if there is an error and +# 1 otherwise. +#**** + +# TODO: Add check for the IPv4/IPv6 addresses +# TODO: Add check for the shared secret field +proc checkIpsecCfg { node strd str } { + + set valid "1" + set ipsecCfgList [getIpsecConfig $node] + + switch $strd { + ipsec-config-id { + foreach ipsecCfg $ipsecCfgList { + set currentid [getConfig $ipsecCfg "ipsec-config-id"] + if { $str == $currentid } { + set valid "0" + } + } + } + } + return $valid +} + +#****f* ipsec.tcl/setConfig +# NAME +# setConfig -- add an element to the ipsec-config +# structure +# SYNOPSIS +# setConfig $strlist $str +# FUNCTION +# Procedure returns requested element that belongs +# to ipsec-config structure. +# INPUTS +# * strlist -- ipsec-config structure +# * cfg -- current ipsec-config that will be extended +# with new elements +# * str -- new element +# RESULT +# * strlist -- new ipsec-config sructure +#**** + +proc setConfig { strlist cfg str } { + + set i [lsearch $strlist "$str *"] + + if { $i < 0 } { + if { $cfg != {} } { + set newcfg [list $str $cfg] + lappend strlist $newcfg + } + } else { + set oldval [lindex [lsearch -inline $strlist "$str *"] 1] + if { $oldval != $cfg } { + set strlist [lreplace $strlist $i $i [list $str $cfg]] + } + } + + return $strlist +} + +#****f* ipsec.tcl/getConfig +# NAME +# getConfig -- get an element of the ipsec-config +# SYNOPSIS +# getConfig $strlist $str +# FUNCTION +# Procedure returns requested element that belongs +# to ipsec-config structure. +# INPUTS +# * strlist -- ipsec-config structure +# * str -- an element of the ipsec-config structure +#**** + +proc getConfig { strlist str } { + + return [lindex [lsearch -inline $strlist "$str *"] 1] +} + + +#****f* ipsec.tcl/setIpsecConfig +# NAME +# setIpsecConfig -- set ipsec configuration +# SYNOPSIS +# setIpsecConfig $node_id $cfg +# FUNCTION +# This procedure adds ipsec-config structure to +# node. +# INPUTS +# * node_id -- node id +#**** + +proc setIpsecConfig { node cfg } { + global $node + + if { $cfg != {} } { + lappend $node [list ipsec-config $cfg] + } + + return +} + +#****f* ipsec.tcl/getIpsecConfig +# NAME +# getIpsecConfig -- get ipsec configuration +# SYNOPSIS +# getIpsecConfig $node_id +# FUNCTION +# This procedure returns list of ipsec-config structures. +# INPUTS +# * node_id -- node id +# RESULT +# * ipsecCfg -- list of ipsec-config structures +#**** + +proc getIpsecConfig { node } { + global $node + set ipsecCfg {} + + set values [lsearch -all -inline [set $node] "ipsec-config *"] + foreach val $values { + lappend ipsecCfg [lindex $val 1] + } + + return $ipsecCfg +} + +#****f* ipsec.tcl/removeIpsecConfig +# NAME +# removeIpsecConfig -- delete all ipsec configuration +# SYNOPSIS +# removeIpsecConfig $node_id +# FUNCTION +# This procedure deletes all ipsec-config structures +# related to specified node. +# INPUTS +# * node_id -- node id +#**** + +proc removeIpsecConfig { node } { + global $node + + set indices [lsearch -all [set $node] "ipsec-config *"] + set cnt 0 + foreach i $indices { + set j [expr $i - $cnt] + set $node [lreplace [set $node] $j $j] + incr cnt + } + return +} + +#****f* ipsec.tcl/getIpsecEnabled +# NAME +# getIpsecEnabled -- get ipsec configuration enabled state +# SYNOPSIS +# set enabled [getIpsecEnabled $node_id] +# FUNCTION +# For input node this procedure returns true if ipsec configuration +# is enabled for the specified node. +# INPUTS +# * node_id -- node id +# RESULT +# * enabled -- returns true if custom configuration is enabled +#**** + +proc getIpsecEnabled { node } { + global $node + + if { [lindex [lsearch -inline [set $node] "ipsec-enabled *"] 1] == true } { + return true + } else { + return false + } +} + +#****f* ipsec.tcl/setIpsecEnabled +# NAME +# setIpsecEnabled -- set ipsec configuration enabled state +# SYNOPSIS +# setIpsecEnabled $node_id $enabled +# FUNCTION +# For input node this procedure enables or disables ipsec configuration. +# INPUTS +# * node_id -- node id +# * enabled -- true if enabling ipsec configuration, false if disabling +#**** + +proc setIpsecEnabled { node enabled } { + global $node + + set i [lsearch [set $node] "ipsec-enabled *"] + if { $i >= 0 } { + set $node [lreplace [set $node] $i $i] + } + if { $enabled == true } { + lappend $node [list ipsec-enabled $enabled] + } + return +} + +#****f* ipsec.tcl/ipsecCfggen +# NAME +# ipsecCfggen -- generate information for the setkey.conf +# SYNOPSIS +# ipsecCfggen $node +# FUNCTION +# Reads all ipsec-configuration and produces data that will be copied +# directly in the setkey.conf while switching to Execute mode. +# INPUTS +# * node -- node id +# RESULT +# * cfg -- information that will be copied into setkey.conf +#**** + +proc ipsecCfggen { node } { + global $node + + set sourceSA "" + set destSA "" + set ipsecalg "" + set ipcomp "" + set inboundspi "" + set outboundspi "" + set cryptoalgesp "" + set cryptoalgah "" + set psk "" + set sourceSP "" + set destSP "" + set sourcesgw "" + set destsgw "" + set traffic "" + set action "" + set spipsecalg "" + set mode "" + set level "" + + set cfg {} + set ipsecCfgList [getIpsecConfig $node] + + lappend cfg "#!/usr/sbin/setkey -f" + lappend cfg "flush;" + lappend cfg "spdflush;" + + foreach ipsecCfg $ipsecCfgList { + set cryptoalg "" + + set sourceSA [getConfig $ipsecCfg "SA-source-address"] + set destSA [getConfig $ipsecCfg "SA-destination-address"] + set ipsecalg [getConfig $ipsecCfg "ipsec-algorithm"] + set ipcomp [getConfig $ipsecCfg "IPcomp-algorithm"] + set inboundspi [getConfig $ipsecCfg "inbound-spi"] + set outboundspi [getConfig $ipsecCfg "outbound-spi"] + set cryptoalgesp [getConfig $ipsecCfg "esp-crypto-algorithm"] + set cryptoalgah [getConfig $ipsecCfg "ah-crypto-algorithm"] + set psk [getConfig $ipsecCfg "shared-secret"] + if { $ipsecalg == "esp" } { + set ipsecalgorithm "esp" + set ipsecalgmark "-E" + append cryptoalg $ipsecalgmark " " $cryptoalgesp + } elseif { $ipsecalg == "ah" } { + set ipsecalgorithm "ah" + set ipsecalgmark "-A" + append cryptoalg $ipsecalgmark " " $cryptoalgah + #} elseif { $ipsecalg == "esp with auth" } { + # set ipsecalgorithm "esp" + # set ipsecalgmark "-E" + # set ipsecalgmark2 "-A" + # append cryptoalg $ipsecalgmark " " $cryptoalgesp " " \ + # $ipsecalgmark2 " " $cryptoalgah + } else { + return "" + } + + # + # TODO: IPcomp: deflate, lzs + # + #if { $ipcomp == "yes" } { + # set ipcompalg " -C deflate" + # append cryptoalg $ipcompalg + #} + + if { $sourceSA != "" && $destSA != "" && \ + $ipsecalg != "" && $cryptoalg != "" && \ + $psk != "" && $inboundspi != "" && \ + $outboundspi != "" } { + + lappend cfg "add $sourceSA $destSA $ipsecalgorithm + $inboundspi $cryptoalg $psk;" + + lappend cfg "add $destSA $sourceSA $ipsecalgorithm + $outboundspi $cryptoalg $psk;" + } + + set sourceSP [getConfig $ipsecCfg "SP-source-address"] + set destSP [getConfig $ipsecCfg "SP-destination-address"] + set sourcesgw [getConfig $ipsecCfg "source-SGW-address"] + set destsgw [getConfig $ipsecCfg "destination-SGW-address"] + set traffic [getConfig $ipsecCfg "traffic-to-process"] + set action [getConfig $ipsecCfg "processing-action"] + set spipsecalg [getConfig $ipsecCfg "SP-ipsec-algorithm"] + set mode [getConfig $ipsecCfg "ipsec-mode"] + set level [getConfig $ipsecCfg "processing-level"] + + if { $sourceSP != "" && $destSP != "" && \ + $traffic != "" && $action != "" && \ + $spipsecalg != "" && $mode != "" && $level != ""} { + + if { $mode == "transport" } { + + lappend cfg "spdadd $sourceSP $destSP $traffic -P out + $action $spipsecalg/$mode//$level;" + lappend cfg "spdadd $destSP $sourceSP $traffic -P in + $action $spipsecalg/$mode//$level;" + + } else { + + if { $sourcesgw != "" && $destsgw != "" } { + + lappend cfg "spdadd $sourceSP $destSP $traffic -P out + $action $spipsecalg/$mode/$sourcesgw-$destsgw/$level;" + lappend cfg "spdadd $destSP $sourceSP $traffic -P in + $action $spipsecalg/$mode/$destsgw-$sourcesgw/$level;" + + } + } + } + } + return $cfg +} -- 2.39.5