-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AC generates token for each knock request. Also added an local http a…
…pi to refresh connection.
- Loading branch information
Showing
9 changed files
with
1,999 additions
and
1,673 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,156 +1,225 @@ | ||
package ac | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/OpenNHP/opennhp/core" | ||
"github.com/OpenNHP/opennhp/log" | ||
"github.com/OpenNHP/opennhp/utils" | ||
|
||
toml "github.com/pelletier/go-toml/v2" | ||
) | ||
|
||
var ( | ||
baseConfigWatch io.Closer | ||
serverConfigWatch io.Closer | ||
|
||
errLoadConfig = fmt.Errorf("config load error") | ||
) | ||
|
||
type Config struct { | ||
PrivateKeyBase64 string `json:"privateKey"` | ||
ACId string `json:"acId"` | ||
DefaultIp string `json:"defaultIp"` | ||
AuthServiceId string `json:"aspId"` | ||
ResourceIds []string `json:"resIds"` | ||
Servers []*core.UdpPeer `json:"servers"` | ||
IpPassMode int `json:"ipPassMode"` // 0: pass the knock source IP, 1: use pre-access mode and release the access source IP | ||
LogLevel int `json:"logLevel"` | ||
} | ||
|
||
type Peers struct { | ||
Servers []*core.UdpPeer | ||
} | ||
|
||
func (d *UdpAC) loadBaseConfig() error { | ||
// config.toml | ||
fileName := filepath.Join(ExeDirPath, "etc", "config.toml") | ||
if err := d.updateBaseConfig(fileName); err != nil { | ||
// report base config error | ||
return err | ||
} | ||
|
||
baseConfigWatch = utils.WatchFile(fileName, func() { | ||
log.Info("base config: %s has been updated", fileName) | ||
d.updateBaseConfig(fileName) | ||
}) | ||
return nil | ||
} | ||
|
||
func (d *UdpAC) loadPeers() error { | ||
// server.toml | ||
fileName := filepath.Join(ExeDirPath, "etc", "server.toml") | ||
if err := d.updateServerPeers(fileName); err != nil { | ||
// ignore error | ||
_ = err | ||
} | ||
|
||
serverConfigWatch = utils.WatchFile(fileName, func() { | ||
log.Info("server peer config: %s has been updated", fileName) | ||
d.updateServerPeers(fileName) | ||
}) | ||
|
||
return nil | ||
} | ||
|
||
func (d *UdpAC) updateBaseConfig(file string) (err error) { | ||
utils.CatchPanicThenRun(func() { | ||
err = errLoadConfig | ||
}) | ||
|
||
content, err := os.ReadFile(file) | ||
if err != nil { | ||
log.Error("failed to read base config: %v", err) | ||
} | ||
|
||
var conf Config | ||
if err := toml.Unmarshal(content, &conf); err != nil { | ||
log.Error("failed to unmarshal base config: %v", err) | ||
} | ||
|
||
if d.config == nil { | ||
d.config = &conf | ||
d.log.SetLogLevel(conf.LogLevel) | ||
return err | ||
} | ||
|
||
// update | ||
if d.config.LogLevel != conf.LogLevel { | ||
log.Info("set base log level to %d", conf.LogLevel) | ||
d.log.SetLogLevel(conf.LogLevel) | ||
d.config.LogLevel = conf.LogLevel | ||
} | ||
|
||
if d.config.DefaultIp != conf.DefaultIp { | ||
log.Info("set default ip mode to %s", conf.DefaultIp) | ||
d.config.DefaultIp = conf.DefaultIp | ||
} | ||
|
||
if d.config.IpPassMode != conf.IpPassMode { | ||
log.Info("set ip pass mode to %d", conf.IpPassMode) | ||
d.config.IpPassMode = conf.IpPassMode | ||
} | ||
|
||
return err | ||
} | ||
|
||
func (d *UdpAC) updateServerPeers(file string) (err error) { | ||
utils.CatchPanicThenRun(func() { | ||
err = errLoadConfig | ||
}) | ||
|
||
content, err := os.ReadFile(file) | ||
if err != nil { | ||
log.Error("failed to read server peer config: %v", err) | ||
} | ||
|
||
// update | ||
var peers Peers | ||
serverPeerMap := make(map[string]*core.UdpPeer) | ||
if err := toml.Unmarshal(content, &peers); err != nil { | ||
log.Error("failed to unmarshal server peer config: %v", err) | ||
} | ||
for _, p := range peers.Servers { | ||
p.Type = core.NHP_SERVER | ||
d.device.AddPeer(p) | ||
serverPeerMap[p.PublicKeyBase64()] = p | ||
} | ||
|
||
// remove old peers from device | ||
d.serverPeerMutex.Lock() | ||
defer d.serverPeerMutex.Unlock() | ||
for pubKey := range d.serverPeerMap { | ||
if _, found := serverPeerMap[pubKey]; !found { | ||
d.device.RemovePeer(pubKey) | ||
} | ||
} | ||
d.serverPeerMap = serverPeerMap | ||
|
||
return err | ||
} | ||
|
||
func (d *UdpAC) IpPassMode() int { | ||
return d.config.IpPassMode | ||
} | ||
|
||
func (d *UdpAC) StopConfigWatch() { | ||
if baseConfigWatch != nil { | ||
baseConfigWatch.Close() | ||
} | ||
if serverConfigWatch != nil { | ||
serverConfigWatch.Close() | ||
} | ||
} | ||
package ac | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/OpenNHP/opennhp/core" | ||
"github.com/OpenNHP/opennhp/log" | ||
"github.com/OpenNHP/opennhp/utils" | ||
|
||
toml "github.com/pelletier/go-toml/v2" | ||
) | ||
|
||
var ( | ||
baseConfigWatch io.Closer | ||
httpConfigWatch io.Closer | ||
serverPeerWatch io.Closer | ||
|
||
errLoadConfig = fmt.Errorf("config load error") | ||
) | ||
|
||
type Config struct { | ||
PrivateKeyBase64 string `json:"privateKey"` | ||
ACId string `json:"acId"` | ||
DefaultIp string `json:"defaultIp"` | ||
AuthServiceId string `json:"aspId"` | ||
ResourceIds []string `json:"resIds"` | ||
Servers []*core.UdpPeer `json:"servers"` | ||
IpPassMode int `json:"ipPassMode"` // 0: pass the knock source IP, 1: use pre-access mode and release the access source IP | ||
LogLevel int `json:"logLevel"` | ||
} | ||
|
||
type HttpConfig struct { | ||
EnableHttp bool | ||
EnableTLS bool | ||
HttpListenPort int | ||
TLSCertFile string | ||
TLSKeyFile string | ||
} | ||
|
||
type Peers struct { | ||
Servers []*core.UdpPeer | ||
} | ||
|
||
func (a *UdpAC) loadBaseConfig() error { | ||
// config.toml | ||
fileName := filepath.Join(ExeDirPath, "etc", "config.toml") | ||
if err := a.updateBaseConfig(fileName); err != nil { | ||
// report base config error | ||
return err | ||
} | ||
|
||
baseConfigWatch = utils.WatchFile(fileName, func() { | ||
log.Info("base config: %s has been updated", fileName) | ||
a.updateBaseConfig(fileName) | ||
}) | ||
return nil | ||
} | ||
|
||
func (a *UdpAC) loadHttpConfig() error { | ||
// http.toml | ||
fileName := filepath.Join(ExeDirPath, "etc", "http.toml") | ||
if err := a.updateHttpConfig(fileName); err != nil { | ||
// ignore error | ||
_ = err | ||
} | ||
|
||
httpConfigWatch = utils.WatchFile(fileName, func() { | ||
log.Info("http config: %s has been updated", fileName) | ||
a.updateHttpConfig(fileName) | ||
}) | ||
return nil | ||
} | ||
|
||
func (a *UdpAC) loadPeers() error { | ||
// server.toml | ||
fileName := filepath.Join(ExeDirPath, "etc", "server.toml") | ||
if err := a.updateServerPeers(fileName); err != nil { | ||
// ignore error | ||
_ = err | ||
} | ||
|
||
serverPeerWatch = utils.WatchFile(fileName, func() { | ||
log.Info("server peer config: %s has been updated", fileName) | ||
a.updateServerPeers(fileName) | ||
}) | ||
|
||
return nil | ||
} | ||
|
||
func (a *UdpAC) updateBaseConfig(file string) (err error) { | ||
utils.CatchPanicThenRun(func() { | ||
err = errLoadConfig | ||
}) | ||
|
||
content, err := os.ReadFile(file) | ||
if err != nil { | ||
log.Error("failed to read base config: %v", err) | ||
} | ||
|
||
var conf Config | ||
if err := toml.Unmarshal(content, &conf); err != nil { | ||
log.Error("failed to unmarshal base config: %v", err) | ||
} | ||
|
||
if a.config == nil { | ||
a.config = &conf | ||
a.log.SetLogLevel(conf.LogLevel) | ||
return err | ||
} | ||
|
||
// update | ||
if a.config.LogLevel != conf.LogLevel { | ||
log.Info("set base log level to %d", conf.LogLevel) | ||
a.log.SetLogLevel(conf.LogLevel) | ||
a.config.LogLevel = conf.LogLevel | ||
} | ||
|
||
if a.config.DefaultIp != conf.DefaultIp { | ||
log.Info("set default ip mode to %s", conf.DefaultIp) | ||
a.config.DefaultIp = conf.DefaultIp | ||
} | ||
|
||
if a.config.IpPassMode != conf.IpPassMode { | ||
log.Info("set ip pass mode to %d", conf.IpPassMode) | ||
a.config.IpPassMode = conf.IpPassMode | ||
} | ||
|
||
return err | ||
} | ||
|
||
func (a *UdpAC) updateHttpConfig(file string) (err error) { | ||
utils.CatchPanicThenRun(func() { | ||
err = errLoadConfig | ||
}) | ||
|
||
content, err := os.ReadFile(file) | ||
if err != nil { | ||
log.Error("failed to read http config: %v", err) | ||
} | ||
|
||
var httpConf HttpConfig | ||
if err := toml.Unmarshal(content, &httpConf); err != nil { | ||
log.Error("failed to unmarshal http config: %v", err) | ||
} | ||
|
||
// update | ||
if httpConf.EnableHttp { | ||
// start http server | ||
if a.httpServer == nil || !a.httpServer.IsRunning() { | ||
if a.httpServer != nil { | ||
// stop old http server | ||
go a.httpServer.Stop() | ||
} | ||
hs := &HttpAC{} | ||
a.httpServer = hs | ||
err = hs.Start(a, &httpConf) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
} else { | ||
// stop http server | ||
if a.httpServer != nil && a.httpServer.IsRunning() { | ||
go a.httpServer.Stop() | ||
a.httpServer = nil | ||
} | ||
} | ||
|
||
a.httpConfig = &httpConf | ||
return err | ||
} | ||
|
||
func (a *UdpAC) updateServerPeers(file string) (err error) { | ||
utils.CatchPanicThenRun(func() { | ||
err = errLoadConfig | ||
}) | ||
|
||
content, err := os.ReadFile(file) | ||
if err != nil { | ||
log.Error("failed to read server peer config: %v", err) | ||
} | ||
|
||
// update | ||
var peers Peers | ||
serverPeerMap := make(map[string]*core.UdpPeer) | ||
if err := toml.Unmarshal(content, &peers); err != nil { | ||
log.Error("failed to unmarshal server peer config: %v", err) | ||
} | ||
for _, p := range peers.Servers { | ||
p.Type = core.NHP_SERVER | ||
a.device.AddPeer(p) | ||
serverPeerMap[p.PublicKeyBase64()] = p | ||
} | ||
|
||
// remove old peers from device | ||
a.serverPeerMutex.Lock() | ||
defer a.serverPeerMutex.Unlock() | ||
for pubKey := range a.serverPeerMap { | ||
if _, found := serverPeerMap[pubKey]; !found { | ||
a.device.RemovePeer(pubKey) | ||
} | ||
} | ||
a.serverPeerMap = serverPeerMap | ||
|
||
return err | ||
} | ||
|
||
func (a *UdpAC) IpPassMode() int { | ||
return a.config.IpPassMode | ||
} | ||
|
||
func (a *UdpAC) StopConfigWatch() { | ||
if baseConfigWatch != nil { | ||
baseConfigWatch.Close() | ||
} | ||
if httpConfigWatch != nil { | ||
httpConfigWatch.Close() | ||
} | ||
if serverPeerWatch != nil { | ||
serverPeerWatch.Close() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.