Permalink
Browse files

hideipvpn and auth-user-pass handling

  • Loading branch information...
hypatia2 committed Oct 26, 2015
1 parent 0c32048 commit dc8a36220503f4084dd872c2ce8199b4577f18b8
Showing with 216 additions and 15 deletions.
  1. +1 −1 .gitignore
  2. +156 −0 fruho/add_hideipvpn.tcl
  3. +2 −0 fruho/add_securitykiss.tcl
  4. +7 −0 fruho/main.tcl
  5. +21 −6 fruhod/main.tcl
  6. +4 −2 fruhod/model.tcl
  7. +22 −4 fruhod/omgmt.tcl
  8. +2 −1 sklib/cmd.tcl
  9. +1 −1 sklib/ovconf.tcl
@@ -6,4 +6,4 @@
/fruho/builddate.txt
/fruho/buildver.txt
/sklib/*.html
t1.tcl
@@ -0,0 +1,156 @@
# This version of hideipvpn config retrieval does not log in to hideipvpn website
# It only takes the static config via VPAPI which is the same for all users
# hideipvpn uses VPN username and password for authentication and shared certificate
namespace eval ::hideipvpn {
namespace export *
namespace ensemble create
variable name hideipvpn
variable dispname HideIpVPN
variable host bootstrap
# port is not relevant - it will be taken from bootstrap nodes list
variable port 10443
variable path_config /vpapi/hideipvpn/config
variable path_plans /vpapi/hideipvpn/plans
# input entries - resettable/modifiable variables
variable newprofilename ""
variable username tgqyqzai
variable password behdfuuu
}
proc ::hideipvpn::create-import-frame {tab} {
variable name
variable dispname
variable newprofilename
set newprofilename [unique-profilename $dispname]
set pconf $tab.$name
ttk::frame $pconf
ttk::label $pconf.profilelabel -text "Profile name" -anchor e
ttk::entry $pconf.profileinput -textvariable ::${name}::newprofilename
ttk::label $pconf.profileinfo -foreground grey
ttk::label $pconf.usernamelabel -text "VPN username" -anchor e
ttk::entry $pconf.usernameinput -textvariable ::${name}::username
ttk::label $pconf.usernameinfo -foreground grey -text ""
ttk::label $pconf.passwordlabel -text "VPN password" -anchor e
ttk::entry $pconf.passwordinput -textvariable ::${name}::password
ttk::label $pconf.passwordinfo -foreground grey
ttk::frame $pconf.importline
ttk::button $pconf.importline.button -text "Import configuration" -command [list go ::${name}::ImportClicked $tab]
# must use non-ttk label for proper animated gif display
label $pconf.importline.img
img place 24/empty $pconf.importline.img
ttk::label $pconf.importline.msg
grid $pconf.importline.button -row 0 -column 0 -padx 10
grid $pconf.importline.img -row 0 -column 1 -padx 10 -pady 10
grid $pconf.importline.msg -row 0 -column 2 -padx 10 -pady 10
grid columnconfigure $pconf 0 -weight 4 -uniform 1
grid columnconfigure $pconf 1 -weight 4 -uniform 1
grid columnconfigure $pconf 2 -weight 4 -uniform 1
grid $pconf.profilelabel -row 1 -column 0 -sticky news -padx 5 -pady 5
grid $pconf.profileinput -row 1 -column 1 -sticky news -padx 5 -pady 5
grid $pconf.profileinfo -row 1 -column 2 -sticky news -pady 5
grid $pconf.usernamelabel -row 5 -column 0 -sticky news -padx 5 -pady 5
grid $pconf.usernameinput -row 5 -column 1 -sticky news -padx 5 -pady 5
grid $pconf.usernameinfo -row 5 -column 2 -sticky news -pady 5
grid $pconf.passwordlabel -row 7 -column 0 -sticky news -padx 5 -pady 5
grid $pconf.passwordinput -row 7 -column 1 -sticky news -padx 5 -pady 5
grid $pconf.passwordinfo -row 7 -column 2 -sticky news -pady 5
grid $pconf.importline -sticky news -columnspan 3
return $pconf
}
proc ::hideipvpn::add-to-treeview-plist {plist} {
variable name
variable dispname
$plist insert {} end -id $name -image [img load 16/logo_$name] -values [list $dispname]
}
# this is csp coroutine
proc ::hideipvpn::ImportClicked {tab} {
try {
variable name
variable dispname
variable host
variable port
variable path_config
variable path_plans
variable username
variable password
variable newprofilename
set profileid [name2id $newprofilename]
set pconf $tab.$name
img place 24/spin $pconf.importline.img
$pconf.importline.msg configure -text "Importing configuration from $dispname"
$pconf.importline.button configure -state disabled
# in case of hideipvpn using username and password has a different purpose than authentication
# instead of using for basic authentication (any strings will pass) the credentials are included in the returned config.ovpn
set result [vpapi-config-direct $newprofilename $host $port $path_config?[this-pcv] $username $password]
# TODO handle vpapi nuncio errors via http error codes: 401 (credentials error), 402 (premium account required), 503 (service unavailable)
if {$result != 200} {
if {$result == 401} {
set msg "Incorrect username or password"
} else {
set msg $result
}
img place 24/empty $pconf.importline.img
$pconf.importline.button configure -state normal
$pconf.importline.msg configure -text $msg
return
}
puts stderr "VPAPI-CONFIG-DIRECT completed"
# in case of hideipvpn using username and password has a different purpose than authentication
# instead of using for basic authentication (any strings will pass) the credentials are included in the returned config.ovpn
set result [vpapi-plans-direct $newprofilename $host $port $path_plans?[this-pcv] $username $password]
# TODO handle vpapi nuncio errors via http error codes: 401 (credentials error), 402 (premium account required), 503 (service unavailable)
if {$result != 200} {
if {$result == 401} {
set msg "Incorrect username/password"
} else {
set msg $result
}
img place 24/empty $pconf.importline.img
$pconf.importline.button configure -state normal
$pconf.importline.msg configure -text $msg
return
}
dict set ::model::Profiles $profileid vpapi_username $username
dict set ::model::Profiles $profileid vpapi_password $password
dict set ::model::Profiles $profileid vpapi_host $host
dict set ::model::Profiles $profileid vpapi_port $port
dict set ::model::Profiles $profileid vpapi_path_plans $path_plans
puts stderr "VPAPI-PLANS-DIRECT completed"
img place 24/empty $pconf.importline.img
$pconf.importline.msg configure -text ""
$pconf.importline.button configure -state normal
set ::${name}::username ""
set ::${name}::password ""
# when repainting tabset select the newly created tab
set ::model::selected_profile $profileid
tabset-profiles .c.tabsetenvelope
} on error {e1 e2} {
puts stderr [log $e1 $e2]
}
}
dict set model::Supported_providers hideipvpn {
name $::hideipvpn::name
dispname $::hideipvpn::dispname
}
@@ -90,6 +90,7 @@ proc ::securitykiss::ImportClicked {tab} {
$pconf.importline.button configure -state disabled
set result [vpapi-config-direct $newprofilename $host $port $path_config?[this-pcv] $username $password]
# TODO handle vpapi nuncio errors via http error codes: 401 (credentials error), 402 (premium account required), 503 (service unavailable)
if {$result != 200} {
if {$result == 401} {
set msg "Incorrect username or password"
@@ -103,6 +104,7 @@ proc ::securitykiss::ImportClicked {tab} {
}
puts stderr "VPAPI-CONFIG-DIRECT completed"
set result [vpapi-plans-direct $newprofilename $host $port $path_plans?[this-pcv] $username $password]
# TODO handle vpapi nuncio errors via http error codes: 401 (credentials error), 402 (premium account required), 503 (service unavailable)
if {$result != 200} {
if {$result == 401} {
set msg "Incorrect username/password"
@@ -810,6 +810,10 @@ proc curl-dispatch {chout cherr hostport args} {
}
# testing command:
# curl --insecure https://fb028f09a9c7d574@37.59.65.55:10443/vpapi/fruho/config?p=linux-x86_64\&c=fb028f09a9c7d574\&v=0.0.7
# or
# curl https://client00000001:xxxxxx@securitykiss.com:10443/vpapi/securitykiss/config
proc vpapi-config-direct {profilename host port urlpath username password} {
try {
set profileid [name2id $profilename]
@@ -971,6 +975,7 @@ proc get-faas-config {} {
if {![is-cert-received fruho]} {
set result [vpapi-cert-direct Fruho bootstrap $port /vpapi/fruho/cert?[this-pcv] $username $password]
# TODO handle vpapi nuncio errors via http error codes: 401 (credentials error), 402 (premium account required), 503 (service unavailable)
if {$result != 200} {
puts stderr [log "ERROR: vpapi-cert-direct Fruho failed with status $result"]
return $result
@@ -979,6 +984,7 @@ proc get-faas-config {} {
}
if {![is-config-received fruho]} {
set result [vpapi-config-direct Fruho bootstrap $port /vpapi/fruho/config?[this-pcv] $username $password]
# TODO handle vpapi nuncio errors via http error codes: 401 (credentials error), 402 (premium account required), 503 (service unavailable)
if {$result != 200} {
puts stderr [log "ERROR: vpapi-config-direct Fruho failed with status $result"]
return $result
@@ -987,6 +993,7 @@ proc get-faas-config {} {
}
if {![dict exists $::model::Profiles fruho plans]} {
set result [vpapi-plans-direct Fruho bootstrap $port /vpapi/fruho/plans?[this-pcv] $username $password]
# TODO handle vpapi nuncio errors via http error codes: 401 (credentials error), 402 (premium account required), 503 (service unavailable)
if {$result != 200} {
puts stderr [log "ERROR: vpapi-plans-direct Fruho failed with status $result"]
return $result
@@ -92,7 +92,7 @@ proc daemon-version-report {} {
proc daemon-model-report {} {
ovpn-pid
catch {ffwrite stat [model model2dict]}
catch {ffwrite stat [model model2dict] 0}
}
proc cyclic-daemon-model-report {} {
@@ -126,7 +126,7 @@ proc ffconn-close {} {
set ::model::Ffconn_sock ""
}
proc ffwrite {prefix msg} {
proc ffwrite {prefix msg {dolog 1}} {
set sock $::model::Ffconn_sock
if {$sock eq ""} {
return
@@ -136,10 +136,16 @@ proc ffwrite {prefix msg} {
log Because of error could not ffwrite: $prefix: $msg
ffconn-close
} else {
log ffwrite: $prefix: $msg
if {$dolog} {
log ffwrite: $prefix: $msg
}
}
}
# ::model::ovpn_config stores the full config with meta info and custom fruho options which is not correct openvpn config
# adjust-config should strip the ovpn config of this data to make the result suitable to pass to openvpn
# Also it should add missing options
# It should produce legal openvpn config
proc adjust-config {conf} {
# adjust management port
set mgmt [::ovconf::get $conf management]
@@ -166,6 +172,15 @@ proc adjust-config {conf} {
# For --proto tcp-client, take 1 as the number of retries of connection attempt (default=infinite).
set conf [::ovconf::cset $conf --connect-retry-max 1]
# For auth-user-pass interactive authentication enforce prompting from mgmt console
if {[::ovconf::index $conf --auth-user-pass] != -1} {
set conf [::ovconf::cset $conf --management-query-passwords]
}
# Remove custom authentication options
set conf [::ovconf::del $conf --custom-auth-user]
set conf [::ovconf::del $conf --custom-auth-pass]
# delete meta info
set conf [::ovconf::del-meta $conf]
return $conf
@@ -228,8 +243,8 @@ proc ffread {} {
set config [adjust-config $::model::ovpn_config]
set ovpncmd "openvpn $config"
try {
set chan [cmd invoke $ovpncmd OvpnExit OvpnRead OvpnErrRead]
set ::model::Start_pid [pid $chan]
set stdinout [cmd invoke $ovpncmd OvpnExit OvpnRead OvpnErrRead]
set ::model::Start_pid [pid $stdinout]
set ::model::Start_pid_tstamp [clock milliseconds]
# this call is necessary to update ovpn_pid
ovpn-pid
@@ -437,7 +452,7 @@ proc OvpnRead {line} {
}
}
default {
#log OPENVPN: $line
#log OPENVPN default: $line
}
}
if {!$ignoreline} {
@@ -28,8 +28,10 @@ namespace eval ::model {
variable Mgmt_state_tstamp 0
# management console client socket
variable Mgmt_sock ""
# management console client connected - this is different from Mgmt_sock. This must be confirmed by the mgmt interface server.
variable Mgmt_clientok 0
# management console client connected - this is different from Mgmt_sock. It must be confirmed by the mgmt interface server.
# This flag is set a few seconds after the mgmt console connection. Mgmt console is not ready to accept commands immediately (probably OpenVPN bug)
# Send commands to mgmt console only when Mgmt_ready is 1. Otherwise it hangs the OpenVPN process.
variable Mgmt_ready 0
# TUN/TAP read bytes
variable mgmt_vread 0
# TUN/TAP write bytes
@@ -2,6 +2,11 @@
# fruhod/omgmt.tcl
#
proc escape-special {s} {
return [string map {\" \\" \\ \\\\ { } {\ }} $s]
}
proc MgmtConnect {} {
catch {MgmtClose}
catch {
@@ -15,8 +20,8 @@ proc MgmtClose {} {
if {$::model::Mgmt_sock ne ""} {
catch {close $::model::Mgmt_sock}
set ::model::Mgmt_sock ""
set ::model::Mgmt_clientok 0
}
set ::model::Mgmt_ready 0
}
proc MgmtRead {sock} {
@@ -73,12 +78,25 @@ proc MgmtRead {sock} {
}
{OpenVPN Management Interface Version} {
# give more delay after MgmtConnect - workaround for the OpenVPN freeze bug
after 3000 set ::model::Mgmt_clientok 1
after 3000 set ::model::Mgmt_ready 1
#puts "OpenVPN welcome: $line"
}
{SUCCESS: hold release succeeded} {
#puts "$line"
}
{PASSWORD:Need 'Auth' username/password} {
log "MGMT: $line"
set username [escape-special [::ovconf::get $::model::ovpn_config --custom-auth-user]]
set password [escape-special [::ovconf::get $::model::ovpn_config --custom-auth-pass]]
MgmtWrite "username \"Auth\" \"$username\""
MgmtWrite "password \"Auth\" \"$password\""
}
{SUCCESS: 'Auth' username entered, but not yet verified} {
log "MGMT: $line"
}
{SUCCESS: 'Auth' password entered, but not yet verified} {
log "MGMT: $line"
}
pre-compress -
post-compress -
pre-decompress -
@@ -131,11 +149,11 @@ proc MgmtConnectionMonitor {} {
if {$::model::Mgmt_sock eq ""} {
MgmtConnect
}
after 500 MgmtConnectionMonitor
after 1000 MgmtConnectionMonitor
}
proc MgmtStatusMonitor {} {
if {$::model::Mgmt_clientok} {
if {$::model::Mgmt_ready} {
MgmtStatus
}
after 400 MgmtStatusMonitor
@@ -9,7 +9,8 @@ proc ::cmd::invoke {command {onexit {}} {onstdout puts} {onstderr {puts stderr}}
lassign [chan pipe] stderr stderrin
lappend command 2>@$stderrin
set stdout [open |$command]
# a+ - open the "command file" for reading and writing. Writing access is necessary if we want to use the resulting channel to push as standard input
set stdout [open |$command a+]
#chan pipe creates a standalone pipe whose read- and write-side channels are returned as a 2-element list, the first element being the read side and the second the write side. Can be useful e.g. to redirect separately stderr and stdout from a subprocess. To do this, spawn with "2>@" or ">@" redirection operators onto the write side of a pipe, and then immediately close it in the parent. This is necessary to get an EOF on the read side once the child has exited or otherwise closed its output.
chan close $stderrin
@@ -89,7 +89,7 @@ proc ::ovconf::del {conf key {value ""}} {
return $conf
}
# set or replace value for given key in config
proc ::ovconf::cset {conf key {value ""}} {
set key [::ovconf::ddash $key]
# save current index of first key...

0 comments on commit dc8a362

Please sign in to comment.