From 6fb6bc66d8a732807eac3f71c71ed9ca390330a6 Mon Sep 17 00:00:00 2001 From: crusader Date: Fri, 22 Sep 2017 18:20:07 +0900 Subject: [PATCH] ing --- auth/auth.go | 201 ++++++++++++++---------------- auth/host.go | 30 ----- auth/network.go | 64 ---------- auth/registration.go | 116 +++++++++++++++++ central/api/module/noauthprobe.go | 45 +++++++ central/client/client.go | 18 +++ commons/handler.go | 2 +- config.json | 6 +- config/config.go | 4 + config/noauth.go | 8 +- config/probe.go | 6 +- main.go | 9 +- noauth.json | 1 - noauthprobe.json | 1 + probe/probe.go | 2 +- util/url/url.go | 20 +++ 16 files changed, 317 insertions(+), 216 deletions(-) delete mode 100644 auth/host.go delete mode 100644 auth/network.go create mode 100644 auth/registration.go create mode 100644 central/api/module/noauthprobe.go delete mode 100644 noauth.json create mode 100644 noauthprobe.json create mode 100644 util/url/url.go diff --git a/auth/auth.go b/auth/auth.go index abc141b..281ce17 100644 --- a/auth/auth.go +++ b/auth/auth.go @@ -2,27 +2,24 @@ package auth import ( "context" - "encoding/base64" - "encoding/json" + "errors" "fmt" "net/http" - "net/url" "path" "time" lfcc "git.loafle.net/commons_go/config" "git.loafle.net/commons_go/logging" + "git.loafle.net/overflow/overflow_probes/central/api/module" + "git.loafle.net/overflow/overflow_probes/central/client" "git.loafle.net/overflow/overflow_probes/commons" "git.loafle.net/overflow/overflow_probes/config" + opuu "git.loafle.net/overflow/overflow_probes/util/url" ) const ( - noAuthConfigFileName = "noauth.json" - noAuthHeaderNoAuthID = "overFlow-NoAuth-ID" - noAuthHeaderNoAuthRegist = "overFlow-NoAuth-Regist" - noAuthHeaderSetNoAuthID = "overFlow-Set-NoAuth-ID" - probeConfigFileName = "probe.json" + noAuthEntryPoint = "/auth" ) type AuthHandler interface { @@ -30,100 +27,127 @@ type AuthHandler interface { } type authHandlers struct { - configDir string + c client.Client + entryURL string + configDir string + noAuthConfigPath string noAuthConfig config.NoAuthProbeConfig - entryURL string - c client.Client - probeConfigPath string - probeConfig config.ProbeConfig + + probeConfigPath string + probeConfig config.ProbeConfig + + shutdownChan chan bool + acceptedChan chan bool + deniedChan chan error } -type NoAuthProbe struct { - APIKey string `json:"apiKey"` - Description string `json:"description"` -} - -type NoAuthDescription struct { - Host Host `json:"host"` - Network Network `json:"network"` -} - -func New(configDir string) AuthHandler { - h := &authHandlers{ - configDir: configDir, - } - +func New(configDir string) (AuthHandler, error) { var err error - var centralURL *url.URL - var noAuthEntryPoint string - var ok bool - if centralURL, err = url.Parse(config.Config.Central.URL); nil != err { - logging.Logger.Error(fmt.Sprintf("Auth: Central URL[%s] is not valid error[%v]", config.Config.Central.URL, err)) - return nil + + h := &authHandlers{ + configDir: configDir, + shutdownChan: make(chan bool), + acceptedChan: make(chan bool), + deniedChan: make(chan error), } - if noAuthEntryPoint, ok = config.Config.Central.EntryPoints["noauth"]; !ok { - logging.Logger.Error("Auth: NoAuth entry point of Central is not exist") - return nil + if h.entryURL, err = opuu.Join(config.Config.Central.URL, noAuthEntryPoint); nil != err { + return nil, err } - centralURL.Path = path.Join(centralURL.Path, noAuthEntryPoint) - h.entryURL = centralURL.String() - - h.noAuthConfigPath = path.Join(configDir, noAuthConfigFileName) - h.probeConfigPath = path.Join(configDir, probeConfigFileName) + h.noAuthConfigPath = path.Join(configDir, config.NoAuthProbeConfigFileName) + h.probeConfigPath = path.Join(configDir, config.ProbeConfigFileName) conf := lfcc.New() if lfcc.Exists(h.noAuthConfigPath) { if err = conf.Load(&h.noAuthConfig, h.noAuthConfigPath); nil != err { - logging.Logger.Error(fmt.Sprintf("Auth: Loading of NoAuth config file[%s] failed error[%v]", h.noAuthConfigPath, err)) + return nil, fmt.Errorf("Auth: Loading of NoAuth config file[%s] failed error[%v]", h.noAuthConfigPath, err) } } else { if err = lfcc.Save(h.noAuthConfig, h.noAuthConfigPath, true); nil != err { - logging.Logger.Error(fmt.Sprintf("Auth: Saving of NoAuth config file[%s] failed error[%v]", h.noAuthConfigPath, err)) + return nil, fmt.Errorf("Auth: Saving of NoAuth config file[%s] failed error[%v]", h.noAuthConfigPath, err) } } - return h + return h, nil } -func (h *authHandlers) Listen() error { - var err error - isRegist := true +func (h *authHandlers) Serve() error { + if nil != h.noAuthConfig.DenyDate { + return fmt.Errorf("Cannot start because this probe have been denied from overFlow[%s]", h.noAuthConfig.DenyDate.String()) + } h.c = client.New() - h.c.OnNotify("NoAuthProbeService.accept", h.onNoAuthProbeAccept) - h.c.OnNotify("NoAuthProbeService.deny", h.onNoAuthProbeDeny) + h.c.OnNotify(module.NoAuthProbeService_AcceptNoAuthProbe, h.onNoAuthProbeAccept) + h.c.OnNotify(module.NoAuthProbeService_DenyNoauthProbe, h.onNoAuthProbeDeny) - header := http.Header{} - - if "" != h.noAuthConfig.TempKey { - isRegist = false - header[noAuthHeaderNoAuthID] = []string{h.noAuthConfig.TempKey} + var err error + if nil != h.noAuthConfig.TempKey && "" != *h.noAuthConfig.TempKey { + err = h.serveConnect(*h.noAuthConfig.TempKey) } else { - var enc string - if enc, err = h.getRegistHeader(); nil != err { + err = h.serveRegistration() + } + if nil != err { + return err + } + +ListenLoop: + for { + select { + case <-h.shutdownChan: + return errors.New("Shutting down") + case <-h.acceptedChan: + break ListenLoop + case err := <-h.deniedChan: return err } - header[noAuthHeaderNoAuthRegist] = []string{enc} } + + return nil +} + +func (h *authHandlers) Shutdown(ctx context.Context) error { + h.shutdownChan <- true + return nil +} + +func (h *authHandlers) serveRegistration() error { + var err error + header := http.Header{} + + var enc string + if enc, err = getRegistHeader(); nil != err { + return err + } + header[module.NoAuthProbeHeader_NoAuthRegist] = []string{enc} + var res *http.Response if res, err = h.c.Dial(h.entryURL, header, 4096, 4096); nil != err { return err } - if isRegist { - h.noAuthConfig.TempKey = res.Header.Get(noAuthHeaderSetNoAuthID) - if err = lfcc.Save(h.noAuthConfig, h.noAuthConfigPath, true); nil != err { - return err - } + tempKey := res.Header.Get(module.NoAuthProbeHeader_SetNoAuthID) + h.noAuthConfig.TempKey = &tempKey + if err = lfcc.Save(h.noAuthConfig, h.noAuthConfigPath, true); nil != err { + return err } - for { + return nil +} +func (h *authHandlers) serveConnect(noAuthTempKey string) error { + var err error + header := http.Header{} + header[module.NoAuthProbeHeader_NoAuthID] = []string{noAuthTempKey} + + var res *http.Response + if res, err = h.c.Dial(h.entryURL, header, 4096, 4096); nil != err { + return err } + logging.Logger.Debug(fmt.Sprintf("Auth: Connect HTTP Status[%s]", res.Status)) + return nil } @@ -138,59 +162,20 @@ func (h *authHandlers) onNoAuthProbeAccept(method string, params interface{}) { } } - h.probeConfig.ID = probeID + h.probeConfig.ID = &probeID if err = lfcc.Save(h.probeConfig, h.probeConfigPath, true); nil != err { logging.Logger.Error(fmt.Sprintf("Auth: Saving of Probe config file[%s] failed error[%v]", h.probeConfigPath, err)) } + h.acceptedChan <- true } func (h *authHandlers) onNoAuthProbeDeny(method string, params interface{}) { - h.noAuthConfig.DenyDate = time.Now() + n := time.Now() + h.noAuthConfig.DenyDate = &n if err := lfcc.Save(h.noAuthConfig, h.noAuthConfigPath, true); nil != err { logging.Logger.Error(fmt.Sprintf("Auth: Saving of NoAuth config file[%s] failed error[%v]", h.noAuthConfigPath, err)) } -} - -func (h *authHandlers) getRegistHeader() (string, error) { - var err error - nap := NoAuthProbe{ - APIKey: config.Config.Domain.APIKey, - } - nad := NoAuthDescription{} - - if err = getHost(&nad.Host); nil != err { - return "", err - } - - if err = getNetwork(&nad.Network); nil != err { - return "", err - } - - var buf []byte - if buf, err = json.Marshal(nad); nil != err { - return "", err - } - nap.Description = string(buf) - - if buf, err = json.Marshal(nap); nil != err { - return "", err - } - - logging.Logger.Debug(fmt.Sprintf("%s", string(buf))) - - enc := base64.StdEncoding.EncodeToString(buf) - - return enc, nil -} - -func (h *authHandlers) listen() { - // 1. regist - // 2. wait for accept auth -} - -func (h *authHandlers) Shutdown(ctx context.Context) error { - - return nil + h.deniedChan <- fmt.Errorf("This probe have been denied from overFlow") } diff --git a/auth/host.go b/auth/host.go deleted file mode 100644 index c1fc7c9..0000000 --- a/auth/host.go +++ /dev/null @@ -1,30 +0,0 @@ -package auth - -import ( - "github.com/shirou/gopsutil/host" -) - -type Host struct { - Name string `json:"name"` - OS string `json:"os"` - Platform string `json:"paltform"` - PlatformFamily string `json:"platformFamily"` - PlatformVersion string `json:"platformVersion"` - KernelVersion string `json:"kernelVersion"` - HostID string `json:"hostID"` -} - -func getHost(h *Host) error { - if i, err := host.Info(); nil == err { - h.Name = i.Hostname - h.OS = i.OS - h.Platform = i.Platform - h.PlatformFamily = i.PlatformFamily - h.KernelVersion = i.KernelVersion - h.HostID = i.HostID - } else { - return err - } - - return nil -} diff --git a/auth/network.go b/auth/network.go deleted file mode 100644 index a653ff2..0000000 --- a/auth/network.go +++ /dev/null @@ -1,64 +0,0 @@ -package auth - -import ( - "bytes" - "errors" - "net" - - "git.loafle.net/commons_go/util/net/gateway" -) - -type Network struct { - Name string `json:"name"` - Address string `json:"address"` - Gateway string `json:"gateway"` - MacAddress string `json:"macAddress"` -} - -func getNetwork(n *Network) error { - var ip net.IP - var iface string - var err error - if ip, iface, err = gateway.DiscoverGateway(); nil != err { - return err - } - - interfaces, err := net.Interfaces() - if err != nil { - return err - } - - idx := -1 - - for _idx, i := range interfaces { - if i.Name == iface { - idx = _idx - break - } - } - - if -1 == idx { - return errors.New("Interface of gateway is not exist") - } - - i := interfaces[idx] - - n.Name = i.Name - n.MacAddress = i.HardwareAddr.String() - n.Gateway = ip.String() - - if addrs, err := i.Addrs(); nil == err { - var buffer bytes.Buffer - for _idx, a := range addrs { - if 0 < _idx { - buffer.WriteString("|") - } - buffer.WriteString(a.String()) - } - n.Address = buffer.String() - } else { - return err - } - - return nil -} diff --git a/auth/registration.go b/auth/registration.go new file mode 100644 index 0000000..8521f52 --- /dev/null +++ b/auth/registration.go @@ -0,0 +1,116 @@ +package auth + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "errors" + "net" + + "git.loafle.net/commons_go/util/net/gateway" + "git.loafle.net/overflow/overflow_probes/central/api/module" + "git.loafle.net/overflow/overflow_probes/config" + "github.com/shirou/gopsutil/host" +) + +func getRegistHeader() (string, error) { + var err error + nap := module.NoAuthProbe{ + APIKey: config.Config.Domain.APIKey, + } + var nad *module.NoAuthProbeDescription + if nad, err = getDescription(); nil != err { + return "", err + } + + var buf []byte + if buf, err = json.Marshal(nad); nil != err { + return "", err + } + nap.Description = string(buf) + + if buf, err = json.Marshal(nap); nil != err { + return "", err + } + + enc := base64.StdEncoding.EncodeToString(buf) + + return enc, nil +} + +func getDescription() (*module.NoAuthProbeDescription, error) { + nad := &module.NoAuthProbeDescription{} + + if err := getHost(&nad.Host); nil != err { + return nil, err + } + + if err := getNetwork(&nad.Network); nil != err { + return nil, err + } + + return nad, nil +} + +func getHost(h *module.NoAuthProbeDescriptionHost) error { + if i, err := host.Info(); nil == err { + h.Name = i.Hostname + h.OS = i.OS + h.Platform = i.Platform + h.PlatformFamily = i.PlatformFamily + h.KernelVersion = i.KernelVersion + h.HostID = i.HostID + } else { + return err + } + + return nil +} + +func getNetwork(n *module.NoAuthProbeDescriptionNetwork) error { + var ip net.IP + var iface string + var err error + if ip, iface, err = gateway.DiscoverGateway(); nil != err { + return err + } + + interfaces, err := net.Interfaces() + if err != nil { + return err + } + + idx := -1 + + for _idx, i := range interfaces { + if i.Name == iface { + idx = _idx + break + } + } + + if -1 == idx { + return errors.New("Interface of gateway is not exist") + } + + i := interfaces[idx] + + n.Name = i.Name + n.MacAddress = i.HardwareAddr.String() + n.Gateway = ip.String() + + if addrs, err := i.Addrs(); nil == err { + var buffer bytes.Buffer + for _idx, a := range addrs { + if 0 < _idx { + buffer.WriteString("|") + } + buffer.WriteString(a.String()) + } + n.Address = buffer.String() + } else { + return err + } + + return nil +} diff --git a/central/api/module/noauthprobe.go b/central/api/module/noauthprobe.go new file mode 100644 index 0000000..0e868d0 --- /dev/null +++ b/central/api/module/noauthprobe.go @@ -0,0 +1,45 @@ +package module + +import "time" + +const ( + NoAuthProbeHeader_NoAuthID = "overFlow-NoAuth-ID" + NoAuthProbeHeader_NoAuthRegist = "overFlow-NoAuth-Regist" + NoAuthProbeHeader_SetNoAuthID = "overFlow-Set-NoAuth-ID" +) + +type NoAuthProbe struct { + ID uint64 `json:"id"` + Description string `json:"description"` + TempProbeKey string `json:"tempProbeKey"` + CreateDate time.Time `json:"createDate"` + APIKey string `json:"apiKey"` +} + +const ( + NoAuthProbeService_Regist = "NoAuthProbeService.regist" + NoAuthProbeService_AcceptNoAuthProbe = "NoAuthProbeService.acceptNoAuthProbe" + NoAuthProbeService_DenyNoauthProbe = "NoAuthProbeService.denyNoauthProbe" +) + +type NoAuthProbeDescription struct { + Host NoAuthProbeDescriptionHost `json:"host"` + Network NoAuthProbeDescriptionNetwork `json:"network"` +} + +type NoAuthProbeDescriptionHost struct { + Name string `json:"name"` + OS string `json:"os"` + Platform string `json:"paltform"` + PlatformFamily string `json:"platformFamily"` + PlatformVersion string `json:"platformVersion"` + KernelVersion string `json:"kernelVersion"` + HostID string `json:"hostID"` +} + +type NoAuthProbeDescriptionNetwork struct { + Name string `json:"name"` + Address string `json:"address"` + Gateway string `json:"gateway"` + MacAddress string `json:"macAddress"` +} diff --git a/central/client/client.go b/central/client/client.go index b0b2a6d..7611b0d 100644 --- a/central/client/client.go +++ b/central/client/client.go @@ -20,6 +20,7 @@ const ( type ( OnNotifyFunc func(method string, params interface{}) + OnCloseFunc func(code int, text string) ) type ServerError string @@ -54,6 +55,7 @@ type Client interface { Call(method string, args interface{}, result interface{}) error Notify(method string, args interface{}) error OnNotify(method string, cb OnNotifyFunc) + OnClose(cb OnCloseFunc) Shutdown(ctx context.Context) error } @@ -68,6 +70,7 @@ type client struct { closing bool // user has called Close shutdown bool // server has told us to stop onNotifyHandlers map[string][]OnNotifyFunc + onCloseHandlers []OnCloseFunc } func New() Client { @@ -75,6 +78,7 @@ func New() Client { requestID: 0, pending: make(map[uint64]*Call), onNotifyHandlers: make(map[string][]OnNotifyFunc), + onCloseHandlers: make([]OnCloseFunc, 1), } return c @@ -93,6 +97,8 @@ func (c *client) Dial(url string, header http.Header, readBufSize int, writeBufS return nil, err } + c.conn.SetCloseHandler(c.connCloseHandler) + go c.input() return res, nil @@ -128,6 +134,10 @@ func (c *client) OnNotify(method string, cb OnNotifyFunc) { hs = append(hs, cb) } +func (c *client) OnClose(cb OnCloseFunc) { + c.onCloseHandlers = append(c.onCloseHandlers, cb) +} + func (c *client) Shutdown(ctx context.Context) error { c.mutex.Lock() if c.closing { @@ -292,3 +302,11 @@ func (c *client) onNotification(noti protocol.Notification) error { return err } + +func (c *client) connCloseHandler(code int, text string) error { + for _, h := range c.onCloseHandlers { + h(code, text) + } + + return nil +} diff --git a/commons/handler.go b/commons/handler.go index c192efe..91cb5fd 100644 --- a/commons/handler.go +++ b/commons/handler.go @@ -3,6 +3,6 @@ package commons import "context" type Handler interface { - Listen() error + Serve() error Shutdown(ctx context.Context) error } diff --git a/config.json b/config.json index 4194558..bd53429 100644 --- a/config.json +++ b/config.json @@ -3,10 +3,6 @@ "apikey": "52abd6fd57e511e7ac52080027658d13" }, "central": { - "url": "ws://127.0.0.1:19190", - "entryPoints": { - "noauth": "/auth", - "probe": "/probe" - } + "url": "ws://127.0.0.1:19190" } } \ No newline at end of file diff --git a/config/config.go b/config/config.go index 134e694..4cb2e59 100644 --- a/config/config.go +++ b/config/config.go @@ -1,5 +1,9 @@ package config +const ( + ConfigFileName = "config.json" +) + var Config AllConfig type AllConfig struct { diff --git a/config/noauth.go b/config/noauth.go index da21ec6..5754888 100644 --- a/config/noauth.go +++ b/config/noauth.go @@ -2,7 +2,11 @@ package config import "time" +const ( + NoAuthProbeConfigFileName = "noauthprobe.json" +) + type NoAuthProbeConfig struct { - TempKey string `json:"tempKey" yaml:"tempKey" toml:"tempKey"` - DenyDate time.Time `json:"denyDate" yaml:"denyDate" toml:"denyDate"` + TempKey *string `json:"tempKey,omitempty" yaml:"tempKey" toml:"tempKey"` + DenyDate *time.Time `json:"denyDate,omitempty" yaml:"denyDate" toml:"denyDate"` } diff --git a/config/probe.go b/config/probe.go index 763cc2b..f53fa07 100644 --- a/config/probe.go +++ b/config/probe.go @@ -1,5 +1,9 @@ package config +const ( + ProbeConfigFileName = "probe.json" +) + type ProbeConfig struct { - ID string `json:"id" yaml:"id" toml:"id"` + ID *string `json:"id,omitempty" yaml:"id" toml:"id"` } diff --git a/main.go b/main.go index fd6105d..b3b287f 100644 --- a/main.go +++ b/main.go @@ -150,16 +150,19 @@ func main() { os.Exit(0) } - handler = auth.New(confDir) + if handler, err = auth.New(confDir); nil != err { + logging.Logger.Error(fmt.Sprintf("Auth: error: %v", err)) + os.Exit(1) + } go func() { - if err := handler.Listen(); err != nil { + if err := handler.Serve(); err != nil { logging.Logger.Error(fmt.Sprintf("Probe: Authenticator error: %v", err)) return } handler = probe.New(confDir) - if err := handler.Listen(); err != nil { + if err := handler.Serve(); err != nil { logging.Logger.Error(fmt.Sprintf("Probe: error: %v", err)) return } diff --git a/noauth.json b/noauth.json deleted file mode 100644 index 65ee62e..0000000 --- a/noauth.json +++ /dev/null @@ -1 +0,0 @@ -{"tempID":""} \ No newline at end of file diff --git a/noauthprobe.json b/noauthprobe.json new file mode 100644 index 0000000..6812a66 --- /dev/null +++ b/noauthprobe.json @@ -0,0 +1 @@ +{"tempKey":"3ca894e0-373a-47d9-a1dd-e4fbd4e214a7"} \ No newline at end of file diff --git a/probe/probe.go b/probe/probe.go index cb7a882..0c245d7 100644 --- a/probe/probe.go +++ b/probe/probe.go @@ -22,7 +22,7 @@ type probe struct { configDir string } -func (p *probe) Listen() error { +func (p *probe) Serve() error { return nil } diff --git a/util/url/url.go b/util/url/url.go new file mode 100644 index 0000000..bf4411d --- /dev/null +++ b/util/url/url.go @@ -0,0 +1,20 @@ +package util + +import ( + "net/url" + "path" +) + +// Join is concat URL string and path +// ex) http://127.0.0.1/ and /entry +func Join(u string, p string) (string, error) { + var err error + var rURL *url.URL + + if rURL, err = url.Parse(u); nil != err { + return "", err + } + + rURL.Path = path.Join(rURL.Path, p) + return rURL.String(), nil +}