mirror of
https://github.com/openziti/desktop-edge-win.git
synced 2026-10-15 17:11:19 +00:00
Merge pull request #419 from openziti/pc-timeout-remaining
Pc timeout remaining
This commit is contained in:
+82
-24
@@ -54,6 +54,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
@@ -82,17 +83,19 @@ type BulkServiceChange struct {
|
||||
ServicesToAdd []*dto.Service
|
||||
MfaMinTimeout int32
|
||||
MfaMaxTimeout int32
|
||||
MfaMinTimeoutRem int32
|
||||
MfaMaxTimeoutRem int32
|
||||
MfaLastUpdatedTime time.Time
|
||||
}
|
||||
|
||||
type NotificationMessage struct {
|
||||
IdentityName string
|
||||
Fingerprint string
|
||||
Message string
|
||||
IdentityName string
|
||||
Fingerprint string
|
||||
Message string
|
||||
MfaMinimumTimeout int32
|
||||
MfaMaximumTimeout int32
|
||||
MfaTimeDuration int
|
||||
Severity string
|
||||
Severity string
|
||||
}
|
||||
|
||||
type TunnelNotificationEvent struct {
|
||||
@@ -156,6 +159,8 @@ type ZIdentity struct {
|
||||
MfaEnabled bool
|
||||
MfaMinTimeout int32
|
||||
MfaMaxTimeout int32
|
||||
MfaMinTimeoutRem int32
|
||||
MfaMaxTimeoutRem int32
|
||||
MfaLastUpdatedTime time.Time
|
||||
}
|
||||
|
||||
@@ -164,8 +169,10 @@ func NewZid(statusChange func(int)) *ZIdentity {
|
||||
zid.Services = sync.Map{}
|
||||
zid.Options = (*C.ziti_options)(C.calloc(1, C.sizeof_ziti_options))
|
||||
zid.StatusChanges = statusChange
|
||||
zid.MfaMinTimeout = -1
|
||||
zid.MfaMinTimeoutRem = -1
|
||||
zid.MfaMaxTimeoutRem = -1
|
||||
zid.MfaMaxTimeout = -1
|
||||
zid.MfaMinTimeout = -1
|
||||
zid.MfaLastUpdatedTime = time.Now()
|
||||
return zid
|
||||
}
|
||||
@@ -247,7 +254,7 @@ func (zid *ZIdentity) Shutdown() {
|
||||
}
|
||||
|
||||
func (zid *ZIdentity) MfaRefreshNeeded() bool {
|
||||
return !(zid.MfaMinTimeout == -1 && zid.MfaMaxTimeout == -1)
|
||||
return !(zid.MfaMinTimeoutRem == -1 && zid.MfaMaxTimeoutRem == -1)
|
||||
}
|
||||
|
||||
func (zid *ZIdentity) GetRemainingTime(timeout int32) int32 {
|
||||
@@ -262,11 +269,11 @@ func (zid *ZIdentity) GetRemainingTime(timeout int32) int32 {
|
||||
|
||||
func (zid *ZIdentity) GetMFAState(interval int32) int {
|
||||
var mfaState int
|
||||
if (zid.MfaMaxTimeout > -1) && (zid.MfaMaxTimeout-int32(time.Since(zid.MfaLastUpdatedTime).Seconds())) < 0 {
|
||||
if (zid.MfaMaxTimeoutRem > -1) && (zid.MfaMaxTimeoutRem-int32(time.Since(zid.MfaLastUpdatedTime).Seconds())) < 0 {
|
||||
mfaState = constants.MfaAllSvcTimeout
|
||||
} else if (zid.MfaMinTimeout - int32(time.Since(zid.MfaLastUpdatedTime).Seconds())) < 0 {
|
||||
} else if (zid.MfaMinTimeoutRem - int32(time.Since(zid.MfaLastUpdatedTime).Seconds())) < 0 {
|
||||
mfaState = constants.MfaFewSvcTimeout
|
||||
} else if (zid.MfaMinTimeout - int32(time.Since(zid.MfaLastUpdatedTime).Seconds())) < interval {
|
||||
} else if (zid.MfaMinTimeoutRem - int32(time.Since(zid.MfaLastUpdatedTime).Seconds())) < interval {
|
||||
mfaState = constants.MfaNearingTimeout
|
||||
} else {
|
||||
mfaState = -1
|
||||
@@ -274,6 +281,31 @@ func (zid *ZIdentity) GetMFAState(interval int32) int {
|
||||
return mfaState
|
||||
}
|
||||
|
||||
func (zid *ZIdentity) UpdateMFATime() {
|
||||
|
||||
zid.Services.Range(func(key interface{}, value interface{}) bool {
|
||||
//string, ZService
|
||||
val := value.(*ZService)
|
||||
|
||||
if zid.MfaRefreshNeeded() && val.Service.Timeout > 0 {
|
||||
var svcTimeout int32 = -1
|
||||
for _, pc := range val.Service.PostureChecks {
|
||||
if svcTimeout == -1 || svcTimeout > int32(pc.Timeout) {
|
||||
svcTimeout = int32(pc.Timeout)
|
||||
}
|
||||
break
|
||||
}
|
||||
atomic.StoreInt32(&val.Service.TimeoutRemaining, svcTimeout)
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
zid.MfaLastUpdatedTime = time.Now()
|
||||
zid.MfaMaxTimeoutRem = zid.MfaMaxTimeout
|
||||
zid.MfaMinTimeoutRem = zid.MfaMinTimeout
|
||||
log.Debugf("updated Mfa Maximum Timeout Remaining to %d and Mfa Minimum Timeout Remaining to %d", zid.MfaMaxTimeoutRem, zid.MfaMinTimeoutRem)
|
||||
}
|
||||
|
||||
//export doZitiShutdown
|
||||
func doZitiShutdown(async *C.uv_async_t) {
|
||||
ctx := C.ziti_context(async.data)
|
||||
@@ -366,6 +398,7 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, z
|
||||
//if any posture query sets pass - that will grant the user access to that service
|
||||
hasAccess := false
|
||||
timeout := -1
|
||||
timeoutRemaining := -1
|
||||
|
||||
//find all posture checks sets...
|
||||
for setIdx := 0; true; setIdx++ {
|
||||
@@ -395,7 +428,7 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, z
|
||||
|
||||
var pcId string
|
||||
pcId = C.GoString(pq.id)
|
||||
log.Infof("Posture query %s, timeout %d", C.GoString(pq.id), int(pq.timeout))
|
||||
log.Infof("Posture query %s, timeout %d, timeoutRemaining %d", C.GoString(pq.id), int(pq.timeout), int(pq.timeoutRemaining))
|
||||
|
||||
_, found := pcIds[pcId]
|
||||
if found {
|
||||
@@ -405,18 +438,23 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, z
|
||||
if timeout == -1 || timeout > int(pq.timeout) {
|
||||
timeout = int(pq.timeout)
|
||||
}
|
||||
if timeoutRemaining == -1 || timeoutRemaining > int(pq.timeoutRemaining) {
|
||||
timeoutRemaining = int(pq.timeoutRemaining)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pcIds[C.GoString(pq.id)] = false
|
||||
pc := dto.PostureCheck{
|
||||
IsPassing: bool(pq.is_passing),
|
||||
QueryType: C.GoString(pq.query_type),
|
||||
Id: pcId,
|
||||
Timeout: int(pq.timeout),
|
||||
IsPassing: bool(pq.is_passing),
|
||||
QueryType: C.GoString(pq.query_type),
|
||||
Id: pcId,
|
||||
Timeout: int(pq.timeout),
|
||||
TimeoutRemaining: int(pq.timeoutRemaining),
|
||||
}
|
||||
timeout = pc.Timeout
|
||||
timeoutRemaining = pc.TimeoutRemaining
|
||||
|
||||
postureChecks = append(postureChecks, pc)
|
||||
}
|
||||
@@ -424,15 +462,16 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, z
|
||||
}
|
||||
|
||||
svc = &dto.Service{
|
||||
Name: name,
|
||||
Id: svcId,
|
||||
Protocols: protocols,
|
||||
Addresses: addresses,
|
||||
Ports: portRanges,
|
||||
OwnsIntercept: true,
|
||||
PostureChecks: postureChecks,
|
||||
IsAccessable: hasAccess,
|
||||
Timeout: int32(timeout),
|
||||
Name: name,
|
||||
Id: svcId,
|
||||
Protocols: protocols,
|
||||
Addresses: addresses,
|
||||
Ports: portRanges,
|
||||
OwnsIntercept: true,
|
||||
PostureChecks: postureChecks,
|
||||
IsAccessable: hasAccess,
|
||||
Timeout: int32(timeout),
|
||||
TimeoutRemaining: int32(timeoutRemaining),
|
||||
}
|
||||
added := ZService{
|
||||
Name: name,
|
||||
@@ -584,6 +623,8 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) {
|
||||
}
|
||||
var minimumTimeout int32 = -1
|
||||
var maximumTimeout int32 = -1
|
||||
var minimumTimeoutRem int32 = -1
|
||||
var maximumTimeoutRem int32 = -1
|
||||
noTimeoutSvc := false
|
||||
if len(servicesToAdd) > 0 {
|
||||
zid.Services.Range(func(key interface{}, value interface{}) bool {
|
||||
@@ -600,17 +641,32 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) {
|
||||
} else {
|
||||
noTimeoutSvc = true
|
||||
}
|
||||
if val.Service.TimeoutRemaining >= 0 {
|
||||
if minimumTimeoutRem == -1 || minimumTimeoutRem > val.Service.TimeoutRemaining {
|
||||
minimumTimeoutRem = val.Service.TimeoutRemaining
|
||||
}
|
||||
if maximumTimeoutRem == -1 || maximumTimeoutRem < val.Service.TimeoutRemaining {
|
||||
maximumTimeoutRem = val.Service.TimeoutRemaining
|
||||
}
|
||||
} else {
|
||||
noTimeoutSvc = true
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
})
|
||||
if noTimeoutSvc {
|
||||
maximumTimeout = -1
|
||||
maximumTimeoutRem = -1
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
zid.MfaMinTimeout = minimumTimeout
|
||||
zid.MfaMaxTimeout = maximumTimeout
|
||||
zid.MfaMinTimeoutRem = minimumTimeoutRem
|
||||
zid.MfaMaxTimeoutRem = maximumTimeoutRem
|
||||
zid.MfaLastUpdatedTime = now
|
||||
|
||||
svcChange := BulkServiceChange{
|
||||
Fingerprint: zid.Fingerprint,
|
||||
@@ -620,7 +676,9 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) {
|
||||
ServicesToRemove: servicesToRemove,
|
||||
MfaMinTimeout: minimumTimeout,
|
||||
MfaMaxTimeout: maximumTimeout,
|
||||
MfaLastUpdatedTime: time.Now(),
|
||||
MfaMinTimeoutRem: minimumTimeoutRem,
|
||||
MfaMaxTimeoutRem: maximumTimeoutRem,
|
||||
MfaLastUpdatedTime: now,
|
||||
}
|
||||
|
||||
if len(BulkServiceChanges) == cap(BulkServiceChanges) {
|
||||
|
||||
@@ -25,7 +25,7 @@ const (
|
||||
MinimumFrequency = 5 // minimum notification window
|
||||
MaximumFrequency = 20 // maximum notification window
|
||||
|
||||
MfaAllSvcTimeout = 0
|
||||
MfaFewSvcTimeout = 1
|
||||
MfaAllSvcTimeout = 0
|
||||
MfaFewSvcTimeout = 1
|
||||
MfaNearingTimeout = 2
|
||||
)
|
||||
|
||||
@@ -32,15 +32,16 @@ type AddIdentity struct {
|
||||
}
|
||||
|
||||
type Service struct {
|
||||
Name string
|
||||
Id string
|
||||
Protocols []string
|
||||
Addresses []Address
|
||||
Ports []PortRange
|
||||
OwnsIntercept bool
|
||||
PostureChecks []PostureCheck
|
||||
IsAccessable bool
|
||||
Timeout int32
|
||||
Name string
|
||||
Id string
|
||||
Protocols []string
|
||||
Addresses []Address
|
||||
Ports []PortRange
|
||||
OwnsIntercept bool
|
||||
PostureChecks []PostureCheck
|
||||
IsAccessable bool
|
||||
Timeout int32
|
||||
TimeoutRemaining int32
|
||||
}
|
||||
|
||||
type Address struct {
|
||||
@@ -56,10 +57,11 @@ type PortRange struct {
|
||||
}
|
||||
|
||||
type PostureCheck struct {
|
||||
IsPassing bool
|
||||
QueryType string
|
||||
Id string
|
||||
Timeout int
|
||||
IsPassing bool
|
||||
QueryType string
|
||||
Id string
|
||||
Timeout int
|
||||
TimeoutRemaining int
|
||||
}
|
||||
|
||||
type ServiceOwner struct {
|
||||
@@ -84,6 +86,8 @@ type Identity struct {
|
||||
Tags []string `json:",omitempty"`
|
||||
MfaMinTimeout int32
|
||||
MfaMaxTimeout int32
|
||||
MfaMinTimeoutRem int32
|
||||
MfaMaxTimeoutRem int32
|
||||
MfaLastUpdatedTime time.Time
|
||||
}
|
||||
type Metrics struct {
|
||||
|
||||
@@ -1196,31 +1196,31 @@ func handleEvents(isInitialized chan struct{}) {
|
||||
|
||||
var notificationMinTimeout int32 = 0
|
||||
var notificationMaxTimeout int32 = -1
|
||||
switch mfaState := id.CId.GetMFAState(int32((constants.MaximumFrequency+rts.state.NotificationFrequency)*60)); mfaState {
|
||||
switch mfaState := id.CId.GetMFAState(int32((constants.MaximumFrequency + rts.state.NotificationFrequency) * 60)); mfaState {
|
||||
case constants.MfaAllSvcTimeout:
|
||||
notificationMessage = fmt.Sprintf("All of the services of identity %s are timed out", id.Name)
|
||||
case constants.MfaFewSvcTimeout:
|
||||
notificationMessage = fmt.Sprintf("Some of the services of identity %s are timed out", id.Name)
|
||||
case constants.MfaNearingTimeout:
|
||||
notificationMinTimeout = id.CId.GetRemainingTime(id.CId.MfaMinTimeout)
|
||||
notificationMinTimeout = id.CId.GetRemainingTime(id.CId.MfaMinTimeoutRem)
|
||||
notificationMessage = fmt.Sprintf("Some of the services of identity %s are timing out in %s", id.Name, secondsToReadableFmt(notificationMinTimeout))
|
||||
default:
|
||||
// do nothing
|
||||
}
|
||||
if len(notificationMessage) > 0 {
|
||||
|
||||
if id.CId.MfaMaxTimeout > -1 {
|
||||
notificationMaxTimeout = id.CId.GetRemainingTime(id.CId.MfaMaxTimeout)
|
||||
if id.CId.MfaMaxTimeoutRem > -1 {
|
||||
notificationMaxTimeout = id.CId.GetRemainingTime(id.CId.MfaMaxTimeoutRem)
|
||||
}
|
||||
notificationMinTimeout = id.CId.GetRemainingTime(id.CId.MfaMinTimeout)
|
||||
notificationMinTimeout = id.CId.GetRemainingTime(id.CId.MfaMinTimeoutRem)
|
||||
|
||||
cleanNotifications = append(cleanNotifications, cziti.NotificationMessage{
|
||||
Fingerprint: id.FingerPrint,
|
||||
IdentityName: id.Name,
|
||||
Severity: "major",
|
||||
Fingerprint: id.FingerPrint,
|
||||
IdentityName: id.Name,
|
||||
Severity: "major",
|
||||
MfaMinimumTimeout: notificationMinTimeout,
|
||||
MfaMaximumTimeout: notificationMaxTimeout,
|
||||
Message: notificationMessage,
|
||||
Message: notificationMessage,
|
||||
MfaTimeDuration: int(time.Since(id.CId.MfaLastUpdatedTime).Seconds()),
|
||||
})
|
||||
}
|
||||
@@ -1272,18 +1272,18 @@ func Clean(src *Id) dto.Identity {
|
||||
//string, ZService
|
||||
val := value.(*cziti.ZService)
|
||||
|
||||
if src.CId.MfaRefreshNeeded() && val.Service.Timeout > 0 {
|
||||
if src.CId.MfaRefreshNeeded() && val.Service.TimeoutRemaining > 0 {
|
||||
var svcTimeout int32 = -1
|
||||
for _, pc := range val.Service.PostureChecks {
|
||||
if svcTimeout == -1 || svcTimeout > int32(pc.Timeout) {
|
||||
svcTimeout = int32(pc.Timeout)
|
||||
if svcTimeout == -1 || svcTimeout > int32(pc.TimeoutRemaining) {
|
||||
svcTimeout = int32(pc.TimeoutRemaining)
|
||||
}
|
||||
break
|
||||
}
|
||||
if (svcTimeout - int32(time.Since(src.CId.MfaLastUpdatedTime).Seconds())) < 0 {
|
||||
atomic.StoreInt32(&val.Service.Timeout, 0)
|
||||
atomic.StoreInt32(&val.Service.TimeoutRemaining, 0)
|
||||
} else {
|
||||
atomic.StoreInt32(&val.Service.Timeout, svcTimeout-int32(time.Since(src.CId.MfaLastUpdatedTime).Seconds()))
|
||||
atomic.StoreInt32(&val.Service.TimeoutRemaining, svcTimeout-int32(time.Since(src.CId.MfaLastUpdatedTime).Seconds()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1292,11 +1292,13 @@ func Clean(src *Id) dto.Identity {
|
||||
})
|
||||
nid.MfaMinTimeout = src.CId.MfaMinTimeout
|
||||
nid.MfaMaxTimeout = src.CId.MfaMaxTimeout
|
||||
nid.MfaMinTimeoutRem = src.CId.MfaMinTimeoutRem
|
||||
nid.MfaMaxTimeoutRem = src.CId.MfaMaxTimeoutRem
|
||||
if !src.CId.MfaRefreshNeeded() {
|
||||
nid.MfaLastUpdatedTime = time.Now()
|
||||
} else {
|
||||
nid.MfaLastUpdatedTime = src.CId.MfaLastUpdatedTime
|
||||
if (nid.MfaMaxTimeout-int32(time.Since(nid.MfaLastUpdatedTime).Seconds())) < 0 && nid.MfaEnabled {
|
||||
if (nid.MfaMaxTimeoutRem-int32(time.Since(nid.MfaLastUpdatedTime).Seconds())) < 0 && nid.MfaEnabled {
|
||||
nid.MfaNeeded = true
|
||||
}
|
||||
}
|
||||
@@ -1322,8 +1324,7 @@ func authMfa(out *json.Encoder, fingerprint string, code string) {
|
||||
id := rts.Find(fingerprint)
|
||||
result := cziti.AuthMFA(id.CId, code)
|
||||
if result == nil {
|
||||
id.CId.MfaNeeded = false
|
||||
id.CId.MfaLastUpdatedTime = time.Now()
|
||||
id.CId.UpdateMFATime()
|
||||
respond(out, dto.Response{Message: "AuthMFA complete", Code: SUCCESS, Error: "", Payload: fingerprint})
|
||||
} else {
|
||||
respondWithError(out, fmt.Sprintf("AuthMFA failed. the supplied code [%s] was not valid: %s", code, result), 1, result)
|
||||
|
||||
@@ -163,6 +163,8 @@ func (t *RuntimeState) ToMetrics() dto.TunnelStatus {
|
||||
MfaNeeded: id.MfaNeeded,
|
||||
MfaMinTimeout: id.MfaMinTimeout,
|
||||
MfaMaxTimeout: id.MfaMaxTimeout,
|
||||
MfaMinTimeoutRem: id.MfaMinTimeoutRem,
|
||||
MfaMaxTimeoutRem: id.MfaMaxTimeoutRem,
|
||||
MfaLastUpdatedTime: id.MfaLastUpdatedTime,
|
||||
}
|
||||
i++
|
||||
|
||||
Reference in New Issue
Block a user