Initial commit

This commit is contained in:
2023-11-22 20:41:41 -07:00
commit d86999ed18
3 changed files with 186 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
module git.ohea.xyz/restitux/nmcli-vpn-activator
go 1.21.4
require git.ohea.xyz/golang/config v0.0.0-20230225082310-91f0f601076e
require github.com/pelletier/go-toml/v2 v2.0.5 // indirect
+14
View File
@@ -0,0 +1,14 @@
git.ohea.xyz/golang/config v0.0.0-20230225082310-91f0f601076e h1:Hwv4cSg2+VG7vk7uOS/WqGIGySmW1xpjs0blo6dfHYc=
git.ohea.xyz/golang/config v0.0.0-20230225082310-91f0f601076e/go.mod h1:86PbXJ2WdqQ+3hYqrnv3ukgKNRK9nQfThnlY03FAO0g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+165
View File
@@ -0,0 +1,165 @@
package main
import (
"fmt"
"os/exec"
"regexp"
"git.ohea.xyz/golang/config"
)
type Config struct {
IgnoreDevices bool
Devices []string
IgnoreConnections bool
Connections []string
VPNConnection string
}
func isMatch(ignoreStrings bool, strings []string, match string) bool {
if ignoreStrings {
for _, s := range strings {
if match == s {
return false
}
}
return true
} else {
for _, s := range strings {
if match == s {
return true
}
}
return false
}
}
func PrintArray(message string, items []string) {
fmt.Printf("%s: ", message)
for i, s := range items {
fmt.Print(s)
if i < len(items)-1 {
fmt.Print(", ")
}
}
fmt.Printf("\n")
}
func enableVPN(vpnCon string) error {
cmd := exec.Command("nmcli", "con", "up", vpnCon)
if err := cmd.Run(); err != nil {
return fmt.Errorf("could not launch VPN: %w\n", err)
}
return nil
}
func disableVPN(vpnCon string) error {
cmd := exec.Command("nmcli", "con", "down", vpnCon)
if err := cmd.Run(); err != nil {
return fmt.Errorf("could not stop VPN: %w\n", err)
}
return nil
}
func main() {
configData := config.Config[Config]{
Name: "nmcli-vpn-activator",
Filename: "config",
Config: Config{
IgnoreDevices: false,
Devices: []string{},
IgnoreConnections: true,
Connections: []string{},
VPNConnection: "",
},
}
new, err := configData.Get()
if err != nil {
fmt.Printf("Could not get config: %w\n", err)
return
}
if new {
fmt.Println("New config created, please update and restart.")
return
}
if configData.Config.IgnoreDevices {
PrintArray("Ignoring the following devices", configData.Config.Devices)
} else {
PrintArray("Enabling the VPN on the following devices", configData.Config.Devices)
}
if configData.Config.IgnoreConnections {
PrintArray("Ignoring the following connections", configData.Config.Connections)
} else {
PrintArray("Enabling the VPN on the following connections", configData.Config.Connections)
}
nmcli_monitor := exec.Command("nmcli", "monitor")
stdout, err := nmcli_monitor.StdoutPipe()
if err != nil {
fmt.Printf("could not get stdout: %w\n", err)
return
}
err = nmcli_monitor.Start()
if err != nil {
fmt.Printf("Could not start process: %w\n", err)
return
}
buf := make([]byte, 1024)
connectingEnable := false
connectingDisable := false
for {
n, err := stdout.Read(buf)
if err != nil {
fmt.Printf("could not read stdout: %w\n, err")
return
}
logLine := string(buf[:n])
usingConnection := regexp.MustCompile(`(?P<device>\S+?): using connection \'(?P<network>.+?)\'`)
results := usingConnection.FindStringSubmatch(logLine)
if len(results) > 0 {
if !isMatch(configData.Config.IgnoreDevices, configData.Config.Devices, results[1]) {
continue
}
if !isMatch(configData.Config.IgnoreConnections, configData.Config.Connections, results[2]) {
fmt.Printf("Monitored device %s has started connecting to VPN disabled network %s.\n", results[1], results[2])
connectingDisable = true
connectingEnable = false
} else {
fmt.Printf("Monitored device %s has started connecting to VPN enabled network %s.\n", results[1], results[2])
connectingEnable = true
connectingDisable = false
}
continue
}
deviceConnected := regexp.MustCompile(`(?P<device>\S+?): connected`)
results = deviceConnected.FindStringSubmatch(logLine)
if len(results) > 0 {
if connectingEnable {
fmt.Printf("Monitored device %s has connected to VPN enabled network, enabling VPN.\n", results[1])
err = enableVPN(configData.Config.VPNConnection)
if err != nil {
fmt.Printf("Could not enable VPN: %w\n", err)
}
connectingEnable = false
}
if connectingDisable {
fmt.Printf("Monitored device %s has connected to VPN disabled network, disabling VPN.\n", results[1])
err = disableVPN(configData.Config.VPNConnection)
if err != nil {
fmt.Printf("Could not disable VPN: %w\n", err)
}
connectingDisable = false
}
}
}
}