refactor ipc into service package

This commit is contained in:
dovholuknf
2020-04-28 22:49:14 -04:00
parent ee10be7de8
commit 75d8a3ccd9
7 changed files with 79 additions and 49 deletions
+11 -13
View File
@@ -10,24 +10,22 @@ import (
"golang.org/x/sys/windows/svc/debug"
"golang.org/x/sys/windows/svc/eventlog"
"wintun-testing/ziti-tunnel/ipc"
pkglog "wintun-testing/ziti-tunnel/log"
"wintun-testing/ziti-tunnel/service"
)
var log = pkglog.Logger
var elog = pkglog.Elog
var log = service.Logger
var elog = service.Elog
func main() {
pkglog.InitLogger("debug")
service.InitLogger("debug")
isIntSess, err := svc.IsAnInteractiveSession()
if err != nil {
log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
}
pkglog.InitEventLog(isIntSess)
defer pkglog.Elog.Close()
service.InitEventLog(isIntSess)
defer service.Elog.Close()
// if not interactive that means this is running as a service via services
if !isIntSess {
@@ -52,9 +50,9 @@ func main() {
}
if !isIntSess {
elog = debug.New(ipc.SvcName)
elog = debug.New(service.SvcName)
} else {
elog, err = eventlog.Open(ipc.SvcName)
elog, err = eventlog.Open(service.SvcName)
if err != nil {
return
}
@@ -65,10 +63,10 @@ func main() {
service.RunService(true)
return
case "install":
elog.Info(service.InstallEvent, "installing service: "+ipc.SvcName)
elog.Info(service.InstallEvent, "installing service: "+service.SvcName)
err = service.InstallService()
case "remove":
elog.Info(service.InstallEvent, "removing service: "+ipc.SvcName)
elog.Info(service.InstallEvent, "removing service: "+service.SvcName)
err = service.RemoveService()
case "start":
err = service.StartService()
@@ -82,8 +80,8 @@ func main() {
usage(fmt.Sprintf("invalid command %s", cmd))
}
if err != nil {
elog.Error(10, fmt.Sprintf("failed to %s %s: %v", cmd, ipc.SvcName, err))
log.Fatalf("failed to %s %s: %v", cmd, ipc.SvcName, err)
elog.Error(10, fmt.Sprintf("failed to %s %s: %v", cmd, service.SvcName, err))
log.Fatalf("failed to %s %s: %v", cmd, service.SvcName, err)
}
return
}
+9 -10
View File
@@ -5,7 +5,6 @@ import (
"fmt"
"os"
"path/filepath"
"wintun-testing/ziti-tunnel/ipc"
"golang.org/x/sys/windows/svc/eventlog"
"golang.org/x/sys/windows/svc/mgr"
@@ -18,10 +17,10 @@ func InstallService() error {
}
defer m.Disconnect()
s, err := m.OpenService(ipc.SvcStartName)
s, err := m.OpenService(SvcStartName)
if err == nil {
s.Close()
return fmt.Errorf("service %s already exists", ipc.SvcStartName)
return fmt.Errorf("service %s already exists", SvcStartName)
}
exePath := os.Args[0]
@@ -35,17 +34,17 @@ func InstallService() error {
}
log.Infof("service installed using path: %s", fullPath)
s, err = m.CreateService(ipc.SvcStartName, fullPath, mgr.Config{
s, err = m.CreateService(SvcStartName, fullPath, mgr.Config{
StartType: mgr.StartAutomatic,
DisplayName: ipc.SvcName,
Description: ipc.SvcNameLong,
DisplayName: SvcName,
Description: SvcNameLong,
})
if err != nil {
return err
}
defer s.Close()
err = eventlog.InstallAsEventCreate(ipc.SvcStartName, eventlog.Error|eventlog.Warning|eventlog.Info)
err = eventlog.InstallAsEventCreate(SvcStartName, eventlog.Error|eventlog.Warning|eventlog.Info)
if err != nil {
s.Delete()
return fmt.Errorf("SetupEventLogSource() failed: %s", err)
@@ -59,16 +58,16 @@ func RemoveService() error {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ipc.SvcStartName)
s, err := m.OpenService(SvcStartName)
if err != nil {
return fmt.Errorf("service %s is not installed", ipc.SvcStartName)
return fmt.Errorf("service %s is not installed", SvcStartName)
}
defer s.Close()
err = s.Delete()
if err != nil {
return err
}
err = eventlog.Remove(ipc.SvcStartName)
err = eventlog.Remove(SvcStartName)
if err != nil {
return fmt.Errorf("RemoveEventLogSource() failed: %s", err)
}
+1 -1
View File
@@ -1,4 +1,4 @@
package ipc
package service
import (
"bufio"
@@ -1,11 +1,9 @@
package log
package service
import (
"io"
"os"
"strings"
"wintun-testing/ziti-tunnel/service"
"github.com/michaelquigley/pfxlog"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows/svc/debug"
@@ -61,9 +59,9 @@ func ParseLevel(lvl string) logrus.Level {
func InitEventLog(interactive bool) {
var err error
if !interactive {
Elog = debug.New(service.SvcName)
Elog = debug.New(SvcName)
} else {
Elog, err = eventlog.Open(service.SvcName)
Elog, err = eventlog.Open(SvcName)
if err != nil {
return
}
+2 -3
View File
@@ -4,7 +4,6 @@ package service
import (
"fmt"
"time"
"wintun-testing/ziti-tunnel/ipc"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
@@ -16,7 +15,7 @@ func StartService() error {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ipc.SvcStartName)
s, err := m.OpenService(SvcStartName)
if err != nil {
return fmt.Errorf("could not access service: %v", err)
}
@@ -34,7 +33,7 @@ func ControlService(c svc.Cmd, to svc.State) error {
return err
}
defer m.Disconnect()
s, err := m.OpenService(ipc.SvcStartName)
s, err := m.OpenService(SvcStartName)
if err != nil {
return fmt.Errorf("could not access service: %v", err)
}
@@ -2,11 +2,32 @@ package service
import (
"github.com/michaelquigley/pfxlog"
"golang.org/x/sys/windows/svc"
"sync"
"wintun-testing/ziti-tunnel/runtime"
)
var log = pfxlog.Logger()
var ipcPipeName = `\\.\pipe\NetFoundry\tunneler\ipc`
var logsPipeName = `\\.\pipe\NetFoundry\tunneler\logs`
var state = runtime.TunnelerState{}
var interrupt chan struct{}
var wg sync.WaitGroup
var connections int
const (
SUCCESS = 0
COULD_NOT_WRITE_FILE = 1
COULD_NOT_ENROLL = 2
UNKNOWN_ERROR = 100
ERROR_DISCONNECTING_ID = 50
IDENTITY_NOT_FOUND = 1000
cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
StartEvent = 1
ContinueEvent = 2
PauseEvent = 3
@@ -15,4 +36,23 @@ const (
StopEvent = 100
ShutdownEvent = 101
ErrorEvent = 500
// This is the name you will use for the NET START command
SvcStartName = "ziti"
// This is the name that will appear in the Services control panel
SvcName = "Ziti Tunneler"
// This is the longer description that will be shown in Services
SvcNameLong = "Provides a client for accessing Ziti networks"
// see: https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-strings
// breaks down to
// "allow" - A (A;;
// "full access" - FA (A;;FA
// "well-known sid" - IU (A;;FA;;;IU)
InteractivelyLoggedInUser = "(A;;GRGW;;;IU)" //generic read/write. We will want to tune this to a specific group but that is not working with Windows 10 home at the moment
System = "(A;;FA;;;SY)"
BuiltinAdmins = "(A;;FA;;;BA)"
LocalService = "(A;;FA;;;LS)"
)
+13 -17
View File
@@ -7,21 +7,17 @@ import (
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/debug"
"wintun-testing/ziti-tunnel/ipc"
log2 "wintun-testing/ziti-tunnel/log"
)
type zitiService struct{}
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
func (m *zitiService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
changes <- svc.Status{State: svc.StartPending}
control := make(chan string)
go func() {
err := ipc.SubMain(control, changes)
err := SubMain(control, changes)
if err != nil {
log.Errorf("the main loop exited with an unexpected error: %v", err)
}
@@ -33,26 +29,26 @@ loop:
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
_ = log2.Elog.Info(ipc.InterrogateEvent, "interrogate request received")
_ = Elog.Info(InterrogateEvent, "interrogate request received")
changes <- c.CurrentStatus
case svc.Stop:
_ = log2.Elog.Info(ipc.StopEvent, "issuing stop")
_ = Elog.Info(StopEvent, "issuing stop")
control <- "stop"
_ = log2.Elog.Info(ipc.StopEvent, "stop issued")
_ = Elog.Info(StopEvent, "stop issued")
break loop
case svc.Shutdown:
_ = log2.Elog.Info(ipc.ShutdownEvent, "issuing shutdown")
_ = Elog.Info(ShutdownEvent, "issuing shutdown")
control <- "stop"
_ = log2.Elog.Info(ipc.ShutdownEvent, "shutdown issued")
_ = Elog.Info(ShutdownEvent, "shutdown issued")
break loop
case svc.Pause:
changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
_ = log2.Elog.Info(ipc.PauseEvent, "request to pause service received. todo - unimplemented")
_ = Elog.Info(PauseEvent, "request to pause service received. todo - unimplemented")
case svc.Continue:
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
_ = log2.Elog.Info(ipc.ContinueEvent, "request to continue service received. todo - unimplemented")
_ = Elog.Info(ContinueEvent, "request to continue service received. todo - unimplemented")
default:
_ = log2.Elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
_ = Elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
}
}
}
@@ -63,16 +59,16 @@ loop:
}
func RunService(isDebug bool) {
_ = log2.Elog.Info(StartEvent, fmt.Sprintf("starting %s service", ipc.SvcStartName))
_ = Elog.Info(StartEvent, fmt.Sprintf("starting %s service", SvcStartName))
run := svc.Run
if isDebug {
run = debug.Run
}
err := run(ipc.SvcStartName, &zitiService{})
err := run(SvcStartName, &zitiService{})
if err != nil {
_ = log2.Elog.Error(ErrorEvent, fmt.Sprintf("%s service failed: %v", ipc.SvcStartName, err))
_ = Elog.Error(ErrorEvent, fmt.Sprintf("%s service failed: %v", SvcStartName, err))
return
}
_ = log2.Elog.Info(StopEvent, fmt.Sprintf("%s service stopped", ipc.SvcStartName))
_ = Elog.Info(StopEvent, fmt.Sprintf("%s service stopped", SvcStartName))
}