]> git.entuzijast.net Git - imunes.git/commitdiff
Added ipsec.tcl
authorana <ana>
Fri, 12 Jan 2007 22:48:39 +0000 (22:48 +0000)
committerana <ana>
Fri, 12 Jan 2007 22:48:39 +0000 (22:48 +0000)
Bug found by:
Submitted by:
Requested by:
Reviewed by:
Approved by:
Obtained from:

ipsec.tcl [new file with mode: 0755]

diff --git a/ipsec.tcl b/ipsec.tcl
new file mode 100755 (executable)
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
+}