--- /dev/null
+#
+# 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
+}