#!/bin/sh # -*- tcl -*- # Executing wish #\ exec wish "$0" "$@" ####################################################################### # # SecPanel - Graphical user interface for managing SSH- and # SCP-connections # # Author: Steffen Leich # http://secpanel.mymediahost.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # ####################################################################### set spversion 0.5.3 set libdir "[file dirname [info script]]/../lib/secpanel" # set libdir "./lib" set sshdir "$env(HOME)/.ssh" set scpcode 0 global actdirsel; global questres; global userres; proc init {argc argv} { global env configs tk_version launcher defident libdir agent wins if {! [info exists env(DISPLAY)] || $env(DISPLAY) == ""} { puts "No valid Xwindow DISPLAY-environment -> exiting SecPanel" exit } set mintcl 8.0 set mintk 8.0 if {[info tclversion]<$mintcl || $tk_version<$mintk} { puts -nonewline stderr "For running SecPanel:\nTcl $mintcl/Tk $mintk minimum versions required. " puts stderr "You have Tcl [info tclversion]/Tk $tk_version" exit 1 } set secpaneldir "$env(HOME)/.secpanel" if {! [file exists $secpaneldir]} { file mkdir $secpaneldir exec chmod 700 $secpaneldir puts "Created config-dir $secpaneldir (chmod 700)..." } if [file exists $secpaneldir/spdata.lck] { puts "Found protected secpanel data" # exec $libdir/protect.sh $libdir exec $libdir/dppw.tcl "de" } if {! [file exists $secpaneldir/.runfiles]} { file mkdir $secpaneldir/.runfiles } if {! [file exists $secpaneldir/profiles]} { file mkdir $secpaneldir/profiles } set configfile "$env(HOME)/.secpanel/config" if {! [file exists $configfile]} { file copy "$libdir/default.config" "$configfile" } source $configfile initconfigs array set gshorts {fore foreground back background} foreach gcolval [array names gshorts] { if [info exists configs($gcolval)] { option add *$gshorts($gcolval) $configs($gcolval) } } array set shorts {entfore Entry.foreground entback Entry.background \ listfore Listbox.foreground listback Listbox.background} foreach colval [array names shorts] { if [info exists configs($colval)] { option add *$shorts($colval) $configs($colval) if {$colval == "listfore"} { option add *Text.foreground $configs($colval) } if {$colval == "listback"} { option add *Text.background $configs($colval) } } } set fb "" set fi "" if {([info exists configs(sysfonts)] && ($configs(sysfonts) != 1)) || ! [info exists configs(sysfonts)]} { if [info exists configs(fontbold)] { if $configs(fontbold) { set fb "bold" } } if [info exists configs(fontitalic)] { if $configs(fontitalic) { set fi "italic" } } if {[info exists configs(fontfam)] && [info exists configs(fontsize)]} { option add *Font "\"$configs(fontfam)\" $configs(fontsize) $fb $fi" } } set agent 0 } proc initconfigs {} { global configs foreach {bintag binprog} \ {sshbin ssh keygenbin ssh-keygen agentbin ssh-agent \ addbin ssh-add askpassbin ssh-askpass scpbin scp xtermbin xterm browserbin firefox \ scanbin scanssh} { if {! [info exists configs($bintag)]} { set configs($bintag) $binprog } } if {! [info exists configs(sshver)]} { set configs(sshver) "OpenSSH" } if {! [info exists configs(termver)]} { set configs(termver) "Xterm" } if {! [info exists configs(lswait)]} { set configs(lswait) "1" } if {! [info exists configs(lsinterpret)]} { set configs(lsinterpret) "tcl" } if {! [info exists configs(scpguiport)]} { set configs(scpguiport) 8820 } if {! [info exists configs(listserverport)]} { set configs(listserverport) 9920 } if {! [info exists configs(controlremoteport)]} { set configs(controlremoteport) 9910 } if {! [info exists configs(controllocalport)]} { set configs(controllocalport) 8810 } if {! [info exists configs(protectdata)]} { set configs(protectdata) 0 } } init $argc $argv proc browsebin {which} { global widget choosefile $widget([set which]ent) "actdirsel" "Open" "" } proc manage_remote {mode} { global widget rfts configs libdir env switch -regexp $mode { init { if {[selection own] == $widget(specsites)} { set actentry [$widget(specsites) get active] set rmprof [retprof $actentry] source "$env(HOME)/.secpanel/profiles/$rmprof.profile" } else { showmessage "No entry selected" "" return } if {[winfo exists .top40]} { if [showconfirm\ "There is another remote management session. Cancel this former session?"\ .top40] { manage_remote cancel } else { return } } set rfts [clock clicks] Window show .top40 .top40.lab51 config -text "Remote Account Manager for $title ($user@$host)" exec $configs(xtermbin) -e $libdir/secpanel_remoteconf.sh $host $user $configs(scpbin) read $rfts set shostsfile "$env(HOME)/.secpanel/.runfiles/ram.$rfts/.shosts" set keysfile "$env(HOME)/.secpanel/.runfiles/ram.$rfts/authorized_keys" if {[file exists $shostsfile]} { $widget(remoteshostsfile) insert end [exec cat $shostsfile] } if {[file exists $keysfile]} { $widget(remotekeysfile) insert end [exec cat $keysfile] } $widget(remotercfile) insert end "Not yet supported, breaks scp..." } cancel { file delete -force "$env(HOME)/.secpanel/.runfiles/ram.$rfts" unset rfts Window destroy .top40 } write { if [showconfirm "Really write back remote configuration?" ".top40"] { set shostsfile [open "$env(HOME)/.secpanel/.runfiles/ram.$rfts/.shosts" w] puts -nonewline $shostsfile [$widget(remoteshostsfile) get 1.0 end] close $shostsfile set keysfile [open "$env(HOME)/.secpanel/.runfiles/ram.$rfts/authorized_keys" w] puts -nonewline $keysfile [$widget(remotekeysfile) get 1.0 end] close $keysfile exec xterm -e lib/secpanel_remoteconf.sh localhost freenet scp write $rfts Window destroy .top40 } } } } proc save_globals {mode} { global widget env configs launcher defident wins set conffile [open "$env(HOME)/.secpanel/config" w] switch -regexp $mode { bins { array set bindefs { \ ssh ssh keygen ssh-keygen agent ssh-agent add ssh-add \ askpass ssh-askpass scp scp xterm xterm browser firefox scan scanssh} foreach f {ssh keygen agent add askpass scp xterm browser scan} { if {[$widget([set f]ent) get] == ""} { $widget([set f]ent) insert 0 $bindefs($f) } puts $conffile "set configs([set f]bin) \"[$widget([set f]ent) get]\"" set configs([set f]bin) [$widget([set f]ent) get] } puts $conffile "set configs(sshver) \"$configs(sshver)\"" puts $conffile "set configs(termver) \"$configs(termver)\"" if [info exists defident] { puts $conffile "set defident \"$defident\"" } puts $conffile "set launcher $launcher" } "geom|startsat|color|fonts|scp|agent|chdef|protectdata" { foreach f {ssh keygen agent add askpass scp xterm browser} { puts $conffile "set configs([set f]bin) \"$configs([set f]bin)\"" } puts $conffile "set configs(sshver) \"$configs(sshver)\"" puts $conffile "set configs(termver) \"$configs(termver)\"" puts $conffile "set launcher $launcher" if [info exists defident] { puts $conffile "set defident \"$defident\"" } } } foreach col {fore back entfore entback listfore listback} { if [info exists configs($col)] { puts $conffile "set configs($col) $configs($col)" } } foreach font {fontfam fontsize fontbold fontitalic sysfonts} { if [info exists configs($font)] { puts $conffile "set configs($font) \"$configs($font)\"" } } if [info exists configs(wingeom)] { puts $conffile "set configs(wingeom) \"$configs(wingeom)\"" } if [info exists configs(protectdata)] { puts $conffile "set configs(protectdata) \"$configs(protectdata)\"" } foreach w [array names wins] { puts $conffile "set wins($w) \"$wins($w)\"" } if [info exists configs(startsat)] { puts $conffile "set configs(startsat) \"$configs(startsat)\"" } foreach scpbool {scpstats scppres scpverb scpcomp scpshowhidden \ lswait lsverbose} { if [info exists configs($scpbool)] { if $configs($scpbool) { puts $conffile "set configs($scpbool) \"$configs($scpbool)\"" } else { puts $conffile "set configs($scpbool) \"$configs($scpbool)\"" } } } if [info exists configs(scpport)] { regsub -all " " $configs(scpport) "" configs(scpport) puts $conffile "set configs(scpport) \"$configs(scpport)\"" } if [info exists configs(lsinterpret)] { puts $conffile "set configs(lsinterpret) \"$configs(lsinterpret)\"" } foreach port {scpgui listserver controlremote controllocal} { puts $conffile "set configs([set port]port) \"$configs([set port]port)\"" } close $conffile showstatus "Global configs saved" } proc chbutton {var but} { global fgdef bgdef if {[set $var]} { $but config -state disabled } else { $but config -state normal } } proc chcol {var button title} { set ret [colorchoose ".top17" $title] if {$ret != ""} { $button config -background $ret } } proc colorchoose {parent title} { set col [tk_chooseColor -parent $parent -title "SecPanel - $title"] return $col } proc fontman {mode} { global configs set names .top23.fra36.cpd37.01 set sizes .top23.fra36.cpd38.01 switch -exact $mode { show { Window show .top23 set names .top23.fra36.cpd37.01 set sizes .top23.fra36.cpd38.01 foreach f [lsort [font families]] { $names insert end $f } set fs 6 while {$fs <= 60} { $sizes insert end $fs incr fs } if $configs(fontbold) { set fb "bold" } else { set fb "" } if $configs(fontitalic) { set fi "italic" } else { set fi "" } if {! $configs(sysfonts)} { if {[info exists configs(fontfam)] && [info exists configs(fontsize)]} { set label "$configs(fontfam) $configs(fontsize)" .top23.lab30 config \ -font "\"$configs(fontfam)\" $configs(fontsize) $fi $fb" } else { set label "" } .top23.lab30 config -text "$label" } else { .top23.lab30 config -text "Using external sysfonts" } set fc 0 if [info exists configs(fontfam)] { foreach fn [$names get 0 end] { if {$fn =="$configs(fontfam)"} { $names activate $fc $names see $fc } incr fc } } set sc 0 if [info exists configs(fontsize)] { foreach fs [$sizes get 0 end] { if {$fs =="$configs(fontsize)"} { $sizes activate $sc $sizes see $sc } incr sc } } # activate listenelement in fontfam und size mit richtigen Werten # font-ex.text mit eingestellten werten } save { set configs(fontfam) [$names get active] set configs(fontsize) [$sizes get active] save_globals fonts Window destroy .top23 } ul { if {! $configs(sysfonts)} { set name [$names get active] set size [$sizes get active] if $configs(fontbold) { set fb "bold" } else { set fb "" } if $configs(fontitalic) { set fi "italic" } else { set fi "" } .top23.lab30 config -text "[$names get active] [$sizes get active]" -font "\"$name\" $size $fi $fb" } else { .top23.lab30 config -text "Using external sysfonts" } } } } proc colorman {mode} { global env configs \ foredef backdef entforedef entbackdef listforedef listbackdef foreach {name widg} {fore 37 back 38 entfore 39 \ entback 40 listfore 41 listback 42} { set colbut[set name] ".top32.fra33.but[set widg]" } set colvals [list fore back entfore entback listfore listback]; switch -exact $mode { 1 { Window show .top32 foreach colval $colvals { if [info exists configs($colval)] { [set colbut[set colval]] configure -background $configs($colval) } else { set [set colval]def 1 } } } save { foreach colval $colvals { if {! [set [set colval]def]} { set configs([set colval]) [[set colbut[set colval]] cget -background] } else { if [info exists configs([set colval])] { unset configs([set colval]) } } } Window destroy .top32 save_globals color } default { set col [colorchoose .top32 "Foreground Color"] if {$col != ""} { [set colbut[set mode]] config \ -background $col -activebackground $col return } else { return } } } } proc showmenu {} { if [winfo exists .pm1] { Window destroy .pm1 } if [winfo exists .pm2] { Window destroy .pm2 } menu .pm1 -tearoff 0 -borderwidth 1 .pm1 add command -label "Connect" -command "connect" .pm1 add command -label "Edit" -command "propconn specsites" .pm1 add command -label "Delete" -command "delconn" .pm1 add command -label "Show info" -state "disabled" .pm1 add command -label "Manage remote account" -command "manage_remote init" .pm1 add cascade -label "Export as..." -menu .pm1.pm2 .pm1 add separator .pm1 add command -label "New connection" -command "newconn 1" menu .pm1.pm2 -tearoff 0 -borderwidth 1 .pm1.pm2 add command -label "Shellscript" -command "export sh" -state "disabled" .pm1.pm2 add command -label "SSH configfile" -command "export ssh" -state "disabled" .pm1.pm2 add command -label "GNOME icon" -command "export gnome" -state "disabled" .pm1.pm2 add command -label "KDE icon" -command "export kde" -state "disabled" tk_popup .pm1 [winfo pointerx .top17] [winfo pointery .top17] } proc historyman {mode "categ {}" "text {}"} { global env histjob configs wins switch -exact $mode { write { set hf [open "$env(HOME)/.secpanel/history" a] puts $hf "$categ#[clock seconds]#$text" close $hf if [winfo exists .top26] { historyman print } } show { Window show .top26 if {[info exists configs(wingeom)] && $configs(wingeom)} { if [info exists wins(hist)] { wm geometry ".top26" $wins(hist) } } set histjob 1 historyman print } report { set repdir "$env(HOME)/.secpanel/reports" if {! [file exists "$repdir"]} { file mkdir "$repdir" } set index [open "$repdir/index.html" w] puts $index "\n\n\n\n\n\n" close $index set header [open "$repdir/header.html" w] puts $header "Report of Secure Shell actions
Generated by SecPanel [exec date]" close $header set panel [open "$repdir/panel.html" w] puts $panel "Actions\n
\nSSH connect
\nSCP connect
\nSCP transfer
\nKeygen
\nKeydist
\nAgent
" close $panel if {! [file exists "$env(HOME)/.secpanel/history"]} { showmessage "No history available" .top26 return } foreach m {1 2 3 4 5 6} { set modef[set m] [open "$repdir/[set m].html" w] puts [set modef[set m]] "\n" } set hf [open "$env(HOME)/.secpanel/history" r] while {[gets $hf line] >= 0} { set elems [split $line "#"] set actmode [set modef[lindex $elems 0]] puts $actmode "\n" } foreach m2 {1 2 3 4 5 6} { puts [set modef[set m2]] "
[clock format [lindex $elems 1]]
[lindex $elems 2]
\n" close [set modef[set m2]] } showmessage "Report for actual history generated in ~/.secpanel/reports/index.html" .top26 exec $configs(browserbin) "file:$env(HOME)/.secpanel/reports/index.html" & } print { set text .top26.cpd27.03 $text delete 1.0 end if {! [file exists "$env(HOME)/.secpanel/history"]} { return } set hf [open "$env(HOME)/.secpanel/history" r] while {[gets $hf line] >= 0} { set elems [split $line "#"] if {[lindex $elems 0] == $histjob} { $text insert end "[clock format [lindex $elems 1]] - [lindex $elems 2]\n" } } $text see end close $hf } clear { if [showconfirm "Really clear the history?\n(Keeping $categ days)" ".top26"] { if {$categ != "0"} { set hfile "$env(HOME)/.secpanel/history" if {! [file exists $hfile]} { showmessage "No history available" .top26 return } set now [clock seconds] set hf [open "$hfile" r] while {[gets $hf line] >= 0} { set elems [split $line "#"] if {[lindex $elems 1] >= [expr $now - ($categ * 24 * 60 * 60)]} { lappend kept $line } } close $hf set hf [open "$hfile" w] foreach l $kept { puts $hf $l } close $hf } else { file delete "$env(HOME)/.secpanel/history" } historyman print } else { return } } } } proc showcomm {mode} { global widget lfstemp rfstemp set actline [$widget([set mode]forwards) get active] if [regsub { -> } $actline : out] { $widget([set mode]fcomment) config -text [set [set mode]fstemp($out)] } } proc add_forw {mode} { global widget lfstemp rfstemp set fhost [$widget([set mode]fhost) get] set fin [$widget([set mode]fin) get] set fout [$widget([set mode]fout) get] set fcomment [$widget([set mode]fcommentent) get] set lhostname "" set rhostname "" if {$fhost == ""} { set fht [set [set mode]hostname] } else { set fht $fhost } if {$fin != "" && $fout != ""} { $widget([set mode]fcomment) config -text "" foreach an [array names [set mode]fstemp] { if {$an == "$fin:$fht:$fout"} { $widget([set mode]fcomment) config -text "Forward exists" return } } $widget([set mode]forwards) insert end "$fin -> $fht:$fout" set [set mode]fstemp($fin:$fht:$fout) $fcomment $widget([set mode]fin) delete 0 end $widget([set mode]fout) delete 0 end $widget([set mode]fhost) delete 0 end $widget([set mode]fcommentent) delete 0 end focus $widget([set mode]fin) $widget([set mode]forwards) see end } } proc del_forw {mode} { global widget lfstemp rfstemp set lwin .top43 set rwin .top51 if {[selection own] == $widget([set mode]forwards)} { set actline [$widget([set mode]forwards) get active] if [regsub { -> } $actline : out] { unset [set mode]fstemp($out) $widget([set mode]forwards) delete active } } else { showmessage "No forwarding selected" [set [set mode]win] } selection clear } proc save_forwards {mode} { global widget rfs rfstemp lfs lfstemp set lwin .top43 set rwin .top51 if [info exists [set mode]fs] { unset [set mode]fs } array set [set mode]fs [array get [set mode]fstemp] if [info exists [set mode]fstemp] { unset [set mode]fstemp } Window destroy [set [set mode]win] } proc open_forwardings {mode} { global widget lfs rfs lfstemp rfstemp set lwin .top43 set rwin .top51 Window show [set [set mode]win] $widget([set mode]forwards) delete 0 end if [info exists [set mode]fstemp] { unset [set mode]fstemp } if [info exists [set mode]fs] { array set [set mode]fstemp [array get [set mode]fs] } foreach fe [array names [set mode]fstemp] { if [regsub : $fe { -> } out] { $widget([set mode]forwards) insert end $out } } } proc changetab {mode} { global libdir agent widget wins configs switch -exact $mode { "small" { if {! [$widget(specsites) index end] > 0} { showmessage "No conncections available, please add one..." "" return } wm withdraw .top17 Window show .top27 if {[info exists configs(wingeom)] && $configs(wingeom)} { if [info exists wins(sat)] { wm geometry ".top27" $wins(sat) } } .top27.but27 config -image [image create photo -file "$libdir/images/swinback_gr.gif"] if {$agent == 1 || $agent == "ext"} { .top27.but27 config -bg green -fg black } else { .top27.but27 config -bg red } specsiteupdate "ss" bind .top27 { changetab big } } "big" { wm withdraw .top27 destroyfilter .top27 Window show .top17 } "default" { foreach f {21 27 35 44 46} { if {[grid info .top17.fra[set f]] != ""} { grid remove .top17.fra[set f] } } array set frames {connect 46 terminal 44 key 35 ssh 21 scp 27} grid .top17.fra$frames($mode) -in .top17 \ -column 0 -row 1 -columnspan 1 -rowspan 1 \ -ipadx 2 -ipady 2 -padx 2 -pady 2 -sticky nesw showstatus "" } } } proc choosefile {{entry ""} {startdir ""} {mode ""} {task ""}} { global actdirsel env widget switch -exact $task { "identityent" { set entry $widget(identityent) set startdir $env(HOME)/.ssh set mode "Open" } "cfgfileent" { set entry $widget(cfgfileent) set startdir $env(HOME)/.ssh set mode "Open" } "keygen" { set entry "$widget(identpath)" set startdir "$env(HOME)/.ssh" set mode "Save" } "*" { } } if {$startdir == "actdirsel"} { if [info exists actdirsel] { set startdir $actdirsel } else { set startdir "/usr/" } } set choice [tk_get[set mode]File -initialdir $startdir] if {$choice != ""} { $entry delete 0 end $entry insert 0 $choice set actdirsel [file dirname $choice] } else { return } } proc showmessage_wizard {text} { global widget $widget(messageline) config -text "$text" } proc distwizard {mode direct} { global widget key connectionprofiles switch -exact $mode { "key" { switchtab_wizard "key" update_keylist $widget(contbutton) config -command "distwizard host f" -text "Continue" -state "active" $widget(backbutton) config -state "disabled" -command "" showmessage_wizard "" } "host" { if {$direct == "f"} { set key [$widget(distkeyentry) get] if {$key == ""} { showmessage_wizard "Please choose key!" return } } switchtab_wizard "host" $widget(contbutton) config -command "distwizard confirm f" -text "Continue" -state "active" $widget(backbutton) config -command "distwizard key b" -state "active" showmessage_wizard "" } "confirm" { if {$direct == "f"} { if {[selection own] != $widget(distconnlist)} { showmessage_wizard "Please choose connection!" return } set connections [$widget(distconnlist) curselection] } set connectiontitles "" set connectionprofiles "" foreach connentry $connections { set connectiontitles [concat $connectiontitles [$widget(distconnlist) get $connentry]] lappend connectionprofiles [retprof [$widget(distconnlist) get $connentry]] } switchtab_wizard "confirm" $widget(finishmessage) config -text "Distribute\n$key\nto connection\n[lsort $connectiontitles]" $widget(contbutton) config -command "distwizard finish f" -text "Distribute key" -state "active" $widget(backbutton) config -command "distwizard host b" -state "active" showmessage_wizard "" } "finish" { Window destroy .top53 distkey "\"$key\"" "$connectionprofiles" } } } proc distkey {key connectionprofiles} { global env widget libdir configs set dfile "$env(HOME)/.secpanel/.runfiles/keydist.[clock clicks]" set df [open "$dfile" w] set drfile "$env(HOME)/.secpanel/.runfiles/keydist_run.[clock clicks]" set drf [open "$drfile" w] foreach actconn $connectionprofiles { source "$env(HOME)/.secpanel/profiles/$actconn.profile" if {$user == ""} { set user [askforuser] if {$user == "#####"} { return } } set singleactstring "$libdir/secpanel.dist $host $user $key $configs(sshbin)" puts $drf $singleactstring puts $drf "\n\n\necho OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO\n\n" historyman write 5 "$key -> $user@$host" } puts $drf "echo echo \"Key-Distribution finished\nPress to continue\" read out exit" close $drf exec chmod +x $drfile switch -regexp $configs(termver) { "GNOME-Term" { set titlepar "-t" set quotepar "\"" } "KDE-Term" { } "Xterm|Rxvt|Aterm" { set titlepar "-title" set quotepar "" } "Eterm" { set titlepar "-T" set quotepar "" } } set actstring "exec $configs(xtermbin) $titlepar \"SecPanel Key-Distribution\" -e $quotepar $drfile $quotepar" puts $df $actstring close $df exec chmod +x $dfile exec $dfile & } proc command_trace {mode "text {}"} { global env configs wins set tracetext ".top24.cpd25.03" set tracefile "$env(HOME)/.secpanel/.runfiles/trace.log" switch -exact $mode { "view" { if {! [winfo exists .top24]} { Window show .top24 if {[info exists configs(wingeom)] && $configs(wingeom)} { if [info exists wins(trace)] { wm geometry ".top24" $wins(trace) } } } $tracetext delete 1.0 end if [file exists "$tracefile"] { set tf [open "$tracefile" r] while {[gets $tf line] >= 0} { set elems [split $line "#"] $tracetext insert end "[clock format [lindex $elems 0]] - [lindex $elems 1]\n" } close $tf } else { $tracetext insert end "No tracelog available" } $tracetext see end } "save" { set tf [open "$tracefile" a] puts $tf "[clock seconds]#[quote_double_space $text]" close $tf if [winfo exists .top24] { command_trace "view" } } } } proc switchtab_wizard {mode} { global widget foreach f {key host confirm} { if {[grid info $widget([set f]frame)] != ""} { grid remove $widget([set f]frame) } } grid $widget([set mode]frame) -in .top53 -column 0 -row 1 -columnspan 1 -rowspan 1 -ipadx 2 -ipady 2 -padx 2 -pady 2 -sticky nesw } proc clear_prmenu {} { global env widget $widget(profiles) delete 0 end foreach prof [lsort [glob -nocomplain "$env(HOME)/.secpanel/profiles/*.profile"]] { $widget(profiles) insert end "[file rootname [file tail $prof]]" } } proc clear_profiles {} { global env widget noagentforward x11forward stricthost nopriv lfs rfs \ verbose quiet fork gateway compress algo compressval \ connwait termicon sshverconnect ipverconnect askuserspec noexec foreach b {noagentforward x11forward stricthost nopriv \ verbose quiet fork gateway compress connwait termicon askuserspec noexec} { set [set b] 0 } set algo "default" set compressval 6 foreach e {host command title subsys identity cfgfile user port profile} { $widget([set e]ent) delete 0 end } if [info exists lfs] { unset lfs } if [info exists rfs] { unset rfs } $widget(userent) insert 0 "$env(USER)" $widget(portent) insert 0 "22" set sshverconnect "2" set ipverconnect "4" if {[winfo exists .top43]} { Window destroy .top43 open_forwardings l } if {[winfo exists .top51]} { Window destroy .top51 open_forwardings r } } proc connect {{cm ""}} { global widget env configs libdir set sshverconnect 1 if {$cm == "ss"} { set actconn [retprof [$widget(sspecsites).sspecmenu entrycget active -label]] } else { if {! [$widget(specsites) index end] > 0} { showmessage "No connections available, please use \"New\"" "" return } if {[selection own] != $widget(specsites)} { showmessage "Please select connection" .top17 return } set connsel [$widget(specsites) curselection] } foreach connselentry $connsel { set actconn [retprof [$widget(specsites) get $connselentry]] source "$env(HOME)/.secpanel/profiles/$actconn.profile" if {$user == ""} { set user [askforuser] if {$user == "#####"} { return } } if {[array size lfs] > 0} { foreach lf [array names lfs] { if {[regsub {} [lindex [split $lf :] 1] $host th]} { append lf_tag " -L [lindex [split $lf :] 0]:$th:[lindex [split $lf :] 2] " } else { append lf_tag " -L [lindex [split $lf :] 0]:[lindex [split $lf :] 1]:[lindex [split $lf :] 2] " } } } else { set lf_tag " " } set localhost [info hostname] if {[array size rfs] > 0} { foreach rf [array names rfs] { if {[regsub {} [lindex [split $rf :] 1] $localhost lh]} { append rf_tag " -R [lindex [split $rf :] 0]:$lh:[lindex [split $rf :] 2] " } else { append rf_tag " -R [lindex [split $rf :] 0]:[lindex [split $rf :] 1]:[lindex [split $rf :] 2] " } } } else { set rf_tag " " } if {$user != ""} { set user_tag "-l $user " } else { set user_tag " " } if {$port == 22 || $port == ""} { set port_tag " " } else { set port_tag "-p $port " } if {$algo != "default" || $algo == ""} { set algo_tag "-c $algo " } else { set algo_tag " " } if {$identity != ""} { set ident_tag "-i $identity " } else { set ident_tag " " } if {[info exists cfgfile] && $cfgfile != ""} { set cfgfile_tag "-F $cfgfile " } else { set cfgfile_tag " " } if {[info exists noagentforward] && $noagentforward} { set noagentforward_tag "-a " } else { set noagentforward_tag "-A " } if {$command != "" && ([info exists noexec] && ! $noexec) && \ ([info exists subsys] && $subsys == "")} { set command_tag "$command" } elseif {[info exists subsys] && $subsys != ""} { set command_tag "-s $subsys" } else { set command_tag "" } if $compress { # openssh if {$configs(sshver) == "OpenSSH"} { set compressval_tag "-o \'CompressionLevel [set compressval]\' " } else { set compressval_tag "-o CompressionLevel=$compressval " } } else { set compressval_tag " " } array set bools { "x11forward" "-x" \ "stricthost" "-o StrictHostKeyChecking=yes" \ "nopriv" "-P" \ "verbose" "-v" \ "quiet" "-q" \ "fork" "-f" \ "gateway" "-g" \ "compress" "-C" \ "noexec" "-N" } # foreach f [array names $bools] foreach f {x11forward stricthost nopriv verbose \ quiet fork gateway compress noexec} { if {[info exists $f] && [set $f]} { set [set f]_tag "$bools($f) " } else { set [set f]_tag " " } } if [info exists sshverconnect] { set sshvertag "-[set sshverconnect] " } if [info exists ipverconnect] { set ipvertag "-[set ipverconnect] " } else { set ipvertag " " } # openssh if {$configs(sshver) == "OpenSSH"} { if {[info exists x11forward] && ! $x11forward} { set x11forward_tag "-X " } if {[info exists noexec] && $noexec} { set noexec_tag "-N " } } set icontag "" switch -regexp $configs(termver) { "GNOME-Term" { set titlepar "-t" set quotepar "\"" if {[info exists termicon] && $termicon} { set icontag "-iconic" } } "KDE-Term" { } "Xterm|Rxvt|Aterm" { set titlepar "-title" set quotepar "" if {[info exists termicon] && $termicon} { set icontag "-iconic" } } "Eterm" { set titlepar "-T" set quotepar "" if {[info exists termicon] && $termicon} { set icontag "--iconic" } } } set waittag "" set woption "" if {[info exists connwait] && $connwait } { set waittag "$libdir/secpanel.wait" set woption "\'" } set cf "$env(HOME)/.secpanel/.runfiles/connect.[clock clicks]" set connfile [open $cf w] set connstring "$configs(sshbin) $user_tag \ $noagentforward_tag $x11forward_tag $noexec_tag $stricthost_tag $sshvertag \ $ipvertag $port_tag $algo_tag \ $ident_tag $cfgfile_tag $nopriv_tag $verbose_tag $quiet_tag \ $fork_tag $gateway_tag $compress_tag $compressval_tag \ $lf_tag $rf_tag $host $command_tag" puts $connfile $connstring close $connfile exec chmod +x $cf set cfr "$cf-run" set crfile [open "$cfr" w] set runstring "exec $configs(xtermbin) $icontag $titlepar \"SSH Connection - $title\" \ -e $quotepar $waittag $woption $cf $woption $quotepar" puts $crfile $runstring close $crfile exec chmod +x $cfr exec $cfr & historyman write 1 "$title" command_trace save "$connstring" } } proc probeversion {} { global widget configs set binstring [$widget(sshent) get] if {$binstring == ""} { set binstring "ssh" } catch {exec $binstring -V} ver if [regexp -nocase "openssh" $ver] { set restext "I guess we have an OpenSSH-version\n\nFound $ver" set configs(sshver) "OpenSSH" } elseif [regexp -nocase "SSH Secure Shell" $ver] { set restext "I guess we have a\nSSH.com-version\n\nFound $ver" set configs(sshver) "SSH.com" } else { set restext "I am not sure about what kind of program is this!\n\nMaybe not a SSH-binary?\nOr doesn't exist at all..." } showmessage "$restext" .top17 } proc showconfirm {text parent} { global questres if {$parent == ""} { set p .top17 } else { set p $parent } set old [focus] Window show .top18 set xcoord [expr [winfo rootx $p] + ([winfo width $p] / 2) - ([winfo width .top18] / 2)] set ycoord [expr [winfo rooty $p] + ([winfo height $p] / 2) - ([winfo height .top18] / 2)] wm geometry .top18 +$xcoord+$ycoord .top18.mes19 config -text "$text" tkwait visibility .top18 focus .top18 grab .top18 tkwait variable questres grab release .top18 focus $old Window destroy .top18 if {$questres} { return 1 } else { return 0 } } proc getuser {} { global widget userres set userres [$widget(askeduser) get] } proc askforuser {"mode c"} { global userres widget set old [focus] Window show .top21 if {$mode == "md"} { wm title .top21 "SecPanel - Make dir" .top21.fra22.mes23 config -text "Enter name of new directory:" .top21.but26 config -text "Make dir" } if {$mode == "protectdata"} { wm title .top21 "SecPanel - Give password for SecPanel data protection" .top21.fra22.mes23 config -text "Enter name of new directory:" .top21.but26 config -text "Make dir" } tkwait visibility .top21 focus $widget(askeduser) grab .top21 tkwait variable userres grab release .top21 focus $old Window destroy .top21 return $userres } proc quote_space {in} { regsub -all " " $in "\\ " out return $out } proc quote_double_space {in} { regsub -all " +" $in " " out return $out } proc showmessage {text parent} { if {$parent == ""} { set p .top17 } else { set p $parent } Window show .top22 .top22.mes23 config -text $text set xcoord [expr [winfo rootx $p] + ([winfo width $p] / 2) - ([winfo width .top22] / 2)] set ycoord [expr [winfo rooty $p] + ([winfo height $p] / 2) - ([winfo height .top22] / 2)] wm geometry .top22 +$xcoord+$ycoord focus .top22 grab .top22 tkwait window .top22 } proc check_sources {mode} { global configs switch -exact $mode { ssh { } sp { exec $configs(browserbin) "http://secpanel.mymediahost.de/?sp_check" & } } } proc delconn {} { global widget env if {[selection own] == $widget(specsites)} { set actentry [$widget(specsites) get active] set delprof [retprof $actentry] if {[showconfirm "Delete $actentry?" ""] == 1} { file delete "$env(HOME)/.secpanel/profiles/$delprof.profile" specsiteupdate clear_prmenu selection clear } else { return } } else { showmessage "No entry selected" "" } } proc delete_profile {} { global env widget set act [$widget(profileent) get] if {$act == ""} { showmessage "To delete a profile first load it" "" return } if {[showconfirm "Delete $act?" ""] == 1} { file delete "$env(HOME)/.secpanel/profiles/$act.profile" clear_prmenu clear_profiles specsiteupdate } } proc hostkey {mode} { global env widget configs hostkeytype set khfile "$env(HOME)/.ssh/known_hosts" catch {exec $configs(keygenbin) -h} ver if [regexp -nocase "F hostname Find hostname" $ver] { set hostkeytype "hashed" } else { set hostkeytype "clear" } switch -exact $mode { edit { Window show .top50 $widget(knownhosts) delete 0 end if { ! [file exists $khfile]} { showmessage "No $khfile found" "" return } if {$hostkeytype=="hashed"} { # handle new hashed hostkey format set profiles [glob -nocomplain "$env(HOME)/.secpanel/profiles/*.profile"] foreach prof [lsort $profiles] { source $prof catch {exec $configs(keygenbin) -F $host} ver if [regexp -nocase "found" $ver] { $widget(knownhosts) insert end $host } } return # end of handling hashed hostkeys } else { set hosts [open $khfile r] while {[gets $hosts line] >= 0} { lappend hl [lindex [split $line] 0] } if {[file size $khfile] > 0} { foreach h [lsort $hl] { $widget(knownhosts) insert end $h } } close $hosts return } } view { keygen info host } export { if {[selection own] != $widget(knownhosts)} { showmessage "No hostkey selected!" ".top50" return } set actk [$widget(knownhosts) get active] set hkf [tk_getSaveFile -initialdir "$env(HOME)"] if {$hkf == ""} { return } else { set hkfout [open "$hkf" w] set hosts [open $khfile r] while {[gets $hosts line] >= 0} { set kparts [split $line] if {[lindex $kparts 0] == $actk} { puts $hkfout $line break } } close $hosts close $hkfout return } } delete { if {[selection own] != $widget(knownhosts)} { showmessage "No hostkey selected!" ".top50" return } set actk [$widget(knownhosts) get active] if {[showconfirm "Delete $actk?" ".top50"] == 1} { if {$hostkeytype=="hashed"} { # handle deletion of hashed hostkeys if [catch {exec $configs(keygenbin) -R $actk} err] { showmessage $err "" } # end handling deletion of hashed hostkeys } else { if [file exists $khfile] { set hosts [open $khfile r] # read lines while {[gets $hosts line] >= 0} { lappend klines $line } close $hosts # write lines set hosts [open $khfile w] foreach line $klines { set kparts [split $line] if {[lindex $kparts 0] != $actk} { puts $hosts $line } } close $hosts } } hostkey edit selection clear } else { return } } } } proc launch_scp {} { global scpcode libdir if {! $scpcode} { source $libdir/sp_scp.tcl set scpcode 1 } scpman open } proc insprot {nr mode} { global widget $widget([set mode]fout) delete 0 end $widget([set mode]fout) insert 0 $nr } proc keygen {mode "in_keytype {}"} { global env widget configs pwtextmode libdir nopass passintext kf keytype switch -regexp $configs(termver) { "GNOME-Term" { set titlepar "-t" set quotepar "\"" } "KDE-Term" { } "Xterm|Rxvt|Aterm" { set titlepar "-title" set quotepar "" } "Eterm" { set titlepar "-T" set quotepar "" } } switch -exact $mode { gen { # comment if {[.top52.fra18.ent24 get] == ""} { set commtag " " } else { set commtag "-C '[.top52.fra18.ent24 get]' " } # file array set ktfiles {"SSH1 RSA1" "identity" "SSH2 RSA" "id_rsa" "SSH2 DSA" "id_dsa"} set ktfile $ktfiles($keytype) set identfile "[$widget(identpath) get]" if {$identfile == ""} { set identfile "$env(HOME)/.ssh/$ktfile" } set filetag "-f $identfile " if [file exists $identfile] { if [showconfirm "$identfile exists. Overwrite?" .top52] { file delete $identfile } else { return } } # pass if {$nopass} { set passtag "-N \"\"" } elseif {$passintext} { set passtag " " } elseif {[.top52.fra18.ent29 get] == ""} { showmessage "Please enter the password for the new key!" .top52 return } else { if {[.top52.fra18.ent29 get] == [.top52.fra18.ent25 get]} { set passtag "-N [.top52.fra18.ent29 get] " } else { showmessage "Password and repeated password are not the same!" .top52 return } } # type array set ktshorts {"SSH1 RSA1" "rsa1" "SSH2 RSA" "rsa" "SSH2 DSA" "dsa"} set typetag "-t $ktshorts($keytype) " set kfile "$env(HOME)/.secpanel/.runfiles/keygen.[clock clicks]" set kf [open "$kfile" w] set kgstring "$configs(keygenbin) $filetag $passtag $typetag $commtag" if {$passintext} { set kgstringt "$configs(keygenbin) $filetag $typetag $commtag" } else { set kgstringt "$configs(keygenbin) $filetag -N ***** $typetag $commtag" } puts $kf $kgstring close $kf exec chmod +x $kfile set cf "$kfile-run" set connfile [open $cf w] set actstring "exec $configs(xtermbin) $titlepar \"SecPanel ssh-keygen\" \ -e $quotepar $libdir/secpanel.wait $kfile $quotepar" puts $connfile $actstring close $connfile exec chmod +x $cf exec $cf file delete "$kfile" file delete "$cf" update_keylist keygen clear command_trace save "$kgstringt" historyman write 4 "$identfile" } "clear" { foreach ke {.top52.fra18.ent24 .top52.fra18.ent29 .top52.fra18.ent29 .top52.fra18.ent25} { [set ke] delete 0 end } $widget(identpath) delete 0 end set keytype "SSH2 DSA" set nopass 0 set passintext 0 set pwtextmode 0 } 0 { set keytype "SSH2 DSA" Window show .top52 .top52.fra18.but27 configure -image [image create photo -file $libdir/images/folder.gif] update_keylist } 1 { if {[selection own] != $widget(keylist)} { showmessage "No key selected!" .top52 return } set kf "$env(HOME)/.ssh/[$widget(keylist) get active]" if [set pwtextmode] { set ksf "$env(HOME)/.secpanel/.runfiles/keychpwd.[clock clicks]" set ksfile [open "$ksf" w] set kstring "$configs(keygenbin) -p -f $kf" puts $ksfile $kstring close $ksfile exec chmod +x $ksf set kcf "$ksf-run" set kcfile [open "$kcf" w] set actstring "exec $configs(xtermbin) $titlepar \"SecPanel - \ change password for $kf\" \ -e $quotepar $libdir/secpanel.wait $ksf $quotepar" puts $kcfile $actstring close $kcfile exec chmod +x $kcf exec $kcf & } else { Window show .top20 $widget(proplabel) config -text $kf } } chpwd { set oldp [.top20.fra21.ent26 get] set newp1 [.top20.fra21.ent30 get] set newp2 [.top20.fra21.ent31 get] if {$newp1 != $newp2} { showmessage "New password and repeated new password don't match" "" return } set chpwdstr "$configs(keygenbin) -p -f $kf -P ***** -N *****" if [catch {exec $configs(keygenbin) -p -f $kf -P $oldp -N $newp1} err] { showmessage $err "" return } Window destroy .top20 command_trace save "$chpwdstr" } info { if {$in_keytype != "host"} { if {[$widget(keylist) index end] == 0} { return } if {[selection own] != $widget(keylist)} { showmessage "No key selected!" .top52 return } set actk [$widget(keylist) get active] set actkfile "$env(HOME)/.ssh/$actk" if {! [file exists "$actkfile"]} { showmessage "Keyfile not found" .top52 return } } else { set khfile "$env(HOME)/.ssh/known_hosts" if {[$widget(knownhosts) index end] == 0} { return } set actk [$widget(knownhosts) get active] if [file exists $khfile] { if {[file size $khfile] > 0} { set hosts [open $khfile r] while {[gets $hosts line] >= 0} { set kparts [split $line] if {[lindex $kparts 0] == $actk} { set fname "$env(HOME)/.secpanel/.runfiles/hkview.[clock clicks]" set af [open "$fname" w] puts $af $line close $af set actkfile "$fname" } } close $hosts } else { showmessage "Keyfile empty" .top50 return } } else { showmessage "Keyfile not found" .top50 return } } set fptext ".top19.tex17" set bbtext ".top19.tex18" if [file exists "$actkfile"] { Window show .top19 if {$in_keytype != "host"} { set kt "user key" } else { set kt "host key" } .top19.fra22.lab23 config -text "Keyfile: $actkfile" .top19.fra22.lab24 config -text "Keytype: $kt" $fptext config -state normal $bbtext config -state normal $fptext delete 1.0 end $bbtext delete 1.0 end $fptext insert end "[exec $configs(keygenbin) -l -f $actkfile]" $bbtext insert end "[exec $configs(keygenbin) -B -f $actkfile]" $fptext config -state disabled $bbtext config -state disabled return } else { showmessage "Couldn't find the public key for this identity!" .top52 return } } del { if {[selection own] != $widget(keylist)} { showmessage "No key selected!" .top52 return } if [showconfirm "Really delete [$widget(keylist) get active]?" .top52] { file delete -force "$env(HOME)/.ssh/[$widget(keylist) get active]" file delete -force "$env(HOME)/.ssh/[$widget(keylist) get active].pub" update_keylist } } chpath { choosefile "" "" "" keygen } dist { Window show .top53 specsiteupdate distwizard key f } } } proc update_keylist {} { global widget env if [winfo exists .top52] { $widget(keylist) delete 0 end } if [winfo exists .top53] { $widget(distkeylist) delete 0 end } set keyfiles [glob -nocomplain "$env(HOME)/.ssh/*.pub"] foreach kf [lsort $keyfiles] { if [winfo exists .top52] { $widget(keylist) insert end [file rootname [file tail $kf]] } if [winfo exists .top53] { $widget(distkeylist) insert end [file rootname [file tail $kf]] } } } proc load_profile {mode} { global env widget noagentforward x11forward stricthost nopriv \ verbose quiet fork gateway compress algo \ compressval lfs rfs connwait termicon sshverconnect \ ipverconnect askuserspec noexec foreach var {noagentforward x11forward stricthost nopriv \ verbose quiet fork gateway compress algo \ compressval lfs rfs connwait termicon askuserspec noexec} { if [info exists [set var]] { unset $var } } foreach rvar {sshverconnect ipverconnect} { if [info exists [set rvar]] { unset $rvar } } if {! [info exists sshverconnect]} { set sshverconnect "2" } if {! [info exists ipverconnect]} { set ipverconnect "4" } if {$mode == "ssh"} { set profile [$widget(profiles) get active] } elseif {$mode == "specsites"} { set profile [retprof [$widget(specsites) get active]] } elseif {$mode == "scphosts"} { set profile [retprof [$widget(scphosts) get active]] } source $env(HOME)/.secpanel/profiles/$profile.profile foreach f {title host user port command subsys identity cfgfile profile} { $widget([set f]ent) delete 0 end if [info exists $f] { $widget([set f]ent) insert 0 [set $f] } } if {! [array exists lfs] && $lfs != ""} { set lfsnew [set lfs] unset lfs foreach listelem $lfsnew { array set lfs \ "[lindex [split $listelem :] 0]::[lindex [split $listelem :] 1] \ {Local forward vom old Version of SecPanel}" } } if {[winfo exists .top43]} { open_forwardings l } if {[winfo exists .top51]} { open_forwardings r } } proc manage_agent {mode "m run"} { global env widget configs launcher defident agent wins switch -exact $mode { "launch" { if {[info exists env(SSH_AGENT_PID)] && [info exists env(SSH_AUTH_SOCK)]} { if {[showconfirm "There seems to be another SSH-Agent. Start anyway?" ""] == 0} { return } } # Start ssh-agent and read envs if {! [file exists "$configs(agentbin)"] && [catch {exec which "$configs(agentbin)"}]} { showmessage "Can't find SSH-Agent ($configs(agentbin))\nCheck configration!" ".top17" changetab terminal return error } set agentout [open "| $configs(agentbin) -c" r] while {[gets $agentout line] >= 0} { if [string match "setenv SSH*" $line] { set env([lindex [split $line] 1]) \ [string trimright [lindex [split $line] 2] \;] } } close $agentout $widget(statusagent) config -text "Agent active" -bg green -fg black $widget(idents) delete 0 end wm title .top17 "SecPanel - Agent active" set agent 1 command_trace save "$configs(agentbin) -c" historyman write 6 "Launching agent" } "kill" { if {$m == "end" && ! $launcher && $agent == "ext"} { return } elseif {$m == "end" && $launcher && $agent != "ext"} { catch {exec $configs(agentbin) -k} killerr unset env(SSH_AGENT_PID) unset env(SSH_AUTH_SOCK) historyman write 6 "Stopping agent" } elseif {$m == "end" && $launcher && $agent == "ext"} { return } else { if [info exists env(SSH_AGENT_PID)] { if {$agent == "ext"} { showmessage "Will not kill external agent!" .top17 return } if {[showconfirm "Kill SSH-agent?" ""] == 1} { exec $configs(agentbin) -k unset env(SSH_AGENT_PID) unset env(SSH_AUTH_SOCK) $widget(statusagent) config -text "No Agent" -bg red wm title .top17 "SecPanel - No Agent" $widget(idents) delete 0 end set agent 0 command_trace save "$configs(agentbin) -k" historyman write 6 "Stopping agent" if [winfo exists .top33] { destroyfilter .top33 } } else { return } } else { showmessage "No agent running" .top17 } } } "info" { if {[info exists env(SSH_AGENT_PID)] && [info exists env(SSH_AUTH_SOCK)]} { Window show .top33 if {[info exists configs(wingeom)] && $configs(wingeom)} { if [info exists wins(agentinfo)] { wm geometry ".top33" $wins(agentinfo) } } .top33.fra34.lab38 config -text $env(SSH_AUTH_SOCK) .top33.fra34.lab39 config -text $env(SSH_AGENT_PID) catch {exec $configs(addbin) -l} err command_trace save "$configs(addbin) -l" set text .top33.cpd36.03 $text delete 1.0 end $text insert end "Fingerprints of keys contained by the running agent:\n\n" $text insert end $err } else { showmessage "No agent running or\nagent environment not clean" .top17 } } "chdef" { set defident [tk_getOpenFile -initialdir "$env(HOME)/.ssh/"] if {$defident != ""} { save_globals chdef historyman write 6 "Setting default identity to $defident" } } "rmdef" { set defident "" save_globals chdef historyman write 6 "Removing default identity" } "addident" { if {! [info exists env(SSH_AGENT_PID)]} { showmessage "No agent running" .top17 return } if {($m == "start")} { if { $launcher && [info exists defident] && $defident != ""} { showstatus "Adding default identity" update idletasks set fname $defident } else { set fname "" } } else { showstatus "Adding identity" update idletasks set fname [tk_getOpenFile -initialdir "$env(HOME)/.ssh/"] } if {$fname != ""} { # openssh if {$configs(sshver) == "OpenSSH"} { set env(SSH_ASKPASS) $configs(askpassbin) } catch {exec $configs(addbin) $fname < /dev/null} err command_trace save "$configs(addbin) $fname < /dev/null" if [string match "*No such file*" $err] { showmessage "Can't find your askpass program-\nCheck configuration!" .top17 return } if [string match "Bad key file*" $err] { showmessage "Bad key file" .top17 return } set found 0 foreach ent [$widget(idents) get 0 end] { if {$ent == $fname} { set found 1 break } } if {! $found} { $widget(idents) insert end $fname } if [winfo exists .top33] { manage_agent "info" } showstatus "" historyman write 6 "Adding identity $fname" } else { showstatus "" return } } "remident" { if {! [info exists env(SSH_AGENT_PID)]} { showmessage "No agent running" .top17 return } if {[selection own] != $widget(idents)} { showmessage "No Identity selected" "" return } else { catch {exec $configs(addbin) -d [$widget(idents) get active]} $widget(idents) delete active selection clear command_trace save "$configs(addbin) -d [$widget(idents) get active]" historyman write 6 "Removing identity [$widget(idents) get active]" if [winfo exists .top33] { manage_agent "info" } } } } } proc newconn {state} { changetab ssh clear_profiles } proc propconn {mode} { global widget if {[selection own] != $widget([set mode])} { showmessage "Please select connection" .top17 return } if {[$widget([set mode]) index end] > 0} { changetab ssh load_profile $mode } else { showmessage "No conncections available, please use \"New\"" "" return } } proc retprof {tit} { global env foreach f [glob -nocomplain "$env(HOME)/.secpanel/profiles/*.profile"] { source $f if {$title == $tit} { return "[file rootname [file tail $f]]" } unset lfs } } proc save_profile {} { global env widget noagentforward x11forward stricthost nopriv verbose \ quiet fork gateway compress algo compressval lfs rfs \ connwait termicon sshverconnect ipverconnect askuserspec noexec set prname [$widget(profileent) get] if {$prname == ""} { showmessage "Enter a name for the profile" "" return } set title [$widget(titleent) get] set host [$widget(hostent) get] set user [$widget(userent) get] if {[info exists askuserspec] && $askuserspec} { set user "" } set port [$widget(portent) get] set command [$widget(commandent) get] set subsys [$widget(subsysent) get] if {$title == "" || $host == ""} { showmessage "You must enter at least host and title" "" return } if {$subsys != "" && ($command != "" || $noexec)} { showmessage "The subsys-entry will be used later (has higher priority)" .top17 } set identity [$widget(identityent) get] set cfgfile [$widget(cfgfileent) get] set prfile [open "$env(HOME)/.secpanel/profiles/$prname.profile" w] puts $prfile "#\n# SecPanel-Profile\n# Do not edit, use SecPanel instead\n#" foreach ent {title host user port command subsys identity cfgfile} { puts $prfile "set [set ent] \"[set $ent]\"" } foreach bool {noagentforward x11forward stricthost nopriv verbose \ quiet fork gateway compress connwait termicon askuserspec noexec} { if [info exists [set bool]] { if [set $bool] { puts $prfile "set [set bool] \"[set $bool]\"" } else { puts $prfile "set [set bool] \"[set $bool]\"" } } } foreach sel {algo compressval} { puts $prfile "set [set sel] \"[set $sel]\"" } puts $prfile "set sshverconnect \"[set sshverconnect]\"" puts $prfile "set ipverconnect \"[set ipverconnect]\"" if [info exists lfs] { puts $prfile "array set lfs {[array get lfs]}" } else { puts $prfile "array set lfs {}" } if [info exists rfs] { puts $prfile "array set rfs {[array get rfs]}" } else { puts $prfile "array set rfs {}" } close $prfile specsiteupdate clear_prmenu clear_profiles } proc seldistkey {} { global env widget set ftypes { {{Public keys} {.pub}} {{All files} *} } $widget(distkeyentry) delete 0 end $widget(distkeyentry) insert 0 \ [tk_getOpenFile -initialdir "$env(HOME)/.ssh" -filetypes $ftypes] } proc showman {man} { global configs exec $configs(xtermbin) -e man $man & } proc specsiteupdate {{mode ""}} { global widget env $widget(specsites) delete 0 end $widget(scphosts) delete 0 end if [winfo exists $widget(distconnlist)] { $widget(distconnlist) delete 0 end } set profiles [glob -nocomplain "$env(HOME)/.secpanel/profiles/*.profile"] if {$mode == "ss"} { if {! [winfo exists $widget(sspecsites).sspecmenu]} { menu $widget(sspecsites).sspecmenu -tearoff 0 -border 1 $widget(sspecsites) config -menu $widget(sspecsites).sspecmenu } else { $widget(sspecsites).sspecmenu delete 0 end } } foreach prof [lsort $profiles] { source $prof $widget(specsites) insert end $title $widget(scphosts) insert end $title if [winfo exists $widget(distconnlist)] { $widget(distconnlist) insert end $title } if {$mode == "ss"} { $widget(sspecsites).sspecmenu add command -label "$title" -command "connect ss" } unset lfs } } proc about {} { global libdir spversion Window show .top25 .top25.fra26.lab21 config -text "SecPanel $spversion" } proc showstatus {text} { global widget $widget(status) config -text $text update idletasks } proc do_firstinit {lv} { global libdir spversion env source $libdir/convert_history.tcl source $libdir/convert_profile.tcl } proc do_exit {} { global env wins libdir configs foreach f [glob -nocomplain "$env(HOME)/.secpanel/.runfiles/*"] { file delete -force $f } if {[info exists env(SSH_AGENT_PID)] && [info exists env(SSH_AUTH_SOCK)]} { manage_agent kill "end" } foreach {winn winnr} {base .top17 trace .top24 scp .top34 sat .top27 agentinfo .top33 hist .top26} { if [winfo exists $winnr] { set wins($winn) [wm geometry $winnr] } } save_globals "geom" # spdata if [set configs(protectdata)] { exec $libdir/dppw.tcl "en" } destroyfilter .top17 exit } proc destroyfilter {win} { global wins foreach {winn winnr} {base .top17 trace .top24 scp .top34 sat .top27 agentinfo .top33 hist .top26} { if {$win == $winnr} { set wins($winn) [wm geometry $win] } } Window destroy $win } proc main {argc argv} { global widget env configs libdir spversion launcher agent wm protocol .top17 WM_DELETE_WINDOW do_exit # bind .top17 { # do_exit # } foreach f {ssh keygen agent add askpass scp xterm browser scan} { $widget([set f]ent) insert 0 "$configs([set f]bin)" } foreach b {connects scp profiles keys configs sscreen} { $widget([set b]but) config -image \ [image create photo -file $libdir/images/[set b]_gr.gif] } set lv 0 if [file exists "$env(HOME)/.secpanel/.init"] { set vf [open "$env(HOME)/.secpanel/.init" r] set lv [read $vf] if {[string equal $spversion $lv] != 1} { do_firstinit $lv exec echo -n $spversion > $env(HOME)/.secpanel/.init } close $vf } else { exec echo -n $spversion > $env(HOME)/.secpanel/.init } clear_prmenu clear_profiles specsiteupdate if {[info exists env(SSH_AGENT_PID)] && [info exists env(SSH_AUTH_SOCK)]} { $widget(statusagent) config -text "Agent active (external)" -bg green -fg black wm title .top17 "SecPanel - Agent active (external)" historyman write 6 "Accepted external agent" set initagentout [open "| ssh-add -L" r] while {[gets $initagentout line] >= 0} { if [string match "The agent has no identities*" $line] { continue } $widget(idents) insert end [lindex [split $line] 2] } set agent "ext" } else { $widget(statusagent) config -text "No Agent" -bg red wm title .top17 "SecPanel - No agent" } if {$launcher} { if {[manage_agent launch] != "error"} { manage_agent addident "start" } } if {[info exists configs(startsat)] && $configs(startsat)} { changetab small } } source $libdir/gui.tcl if {[info exists configs(wingeom)] && $configs(wingeom)} { if [info exists wins(base)] { wm geometry ".top17" $wins(base) } } foreach b {.top17.fra44.fra19.fra20.but23 .top17.fra44.fra19.fra26.03 \ .top17.fra44.fra19.fra27.03 .top17.fra44.fra19.fra28.03 \ .top17.fra44.fra19.fra29.03 .top17.fra44.fra19.fra32.03 \ .top17.fra44.fra19.fra30.03 .top17.fra21.fra24.but22 \ .top17.fra21.fra24.but23 .top17.fra44.fra19.fra18.03 \ .top17.fra44.fra19.fra17.but19} { $b configure -image [image create photo -file $libdir/images/folder.gif] } main $argc $argv