From e4839985cfd4c96e7943e96ad130555f66068d2c Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 1 Feb 2022 20:29:15 -0500 Subject: [PATCH 1/6] allow reconfiguring an endpoint to point to the new controller address --- release-notes.md | 14 +++++++ service/cziti/sdk.c | 4 ++ service/cziti/sdk.go | 7 +++- service/cziti/sdk.h | 1 + service/debug.bat | 2 +- service/ziti-tunnel/api/api.go | 1 + service/ziti-tunnel/service/state.go | 55 ++++++++++++++++++++++++++++ version | 2 +- 8 files changed, 83 insertions(+), 3 deletions(-) diff --git a/release-notes.md b/release-notes.md index 343646c7..252f0f39 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,3 +1,17 @@ +# Release 1.11.1 + +## What's New +* supports reconfiguring an endpoint to point to a new controller address via ziti_api_event + +## Other changes: +* none + +## Bugs fixed: +* none + +## Dependency Updates +* none + # Release 1.10.14 ## What's New diff --git a/service/cziti/sdk.c b/service/cziti/sdk.c index 0af87980..e9a66936 100644 --- a/service/cziti/sdk.c +++ b/service/cziti/sdk.c @@ -95,6 +95,10 @@ struct ziti_service_event* ziti_event_service_event(ziti_event_t *ev) { return &ev->event.service; } +struct ziti_api_event* ziti_event_api_event(ziti_event_t *ev) { + return &ev->event.api; +} + ziti_service* ziti_service_array_get(ziti_service_array arr, int idx) { return arr ? arr[idx] : NULL; } diff --git a/service/cziti/sdk.go b/service/cziti/sdk.go index 9aa3fbc3..1f470872 100644 --- a/service/cziti/sdk.go +++ b/service/cziti/sdk.go @@ -757,6 +757,11 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) { } else { log.Debugf("mfa auth event set received with empty finger print, ziti context [%p]", zid) } + case C.ZitiAPIEvent: + apiEvent := C.ziti_event_api_event(event) + newAddress := C.GoString(apiEvent.new_ctrl_address) + cfgPath := C.GoString(zid.Options.config) + goapi.UpdateAddress(cfgPath, newAddress) default: log.Infof("event %d not handled", event._type) } @@ -809,7 +814,7 @@ func LoadZiti(zid *ZIdentity, cfg string, refreshInterval int, apiPageSize int) zid.Options.pq_os_cb = C.ziti_pq_os_cb(C.ziti_pq_os_go) zid.Options.pq_process_cb = C.ziti_pq_process_cb(C.ziti_pq_process_go) zid.Options.api_page_size = C.uint32_t(apiPageSize) - zid.Options.events = C.ZitiContextEvent | C.ZitiServiceEvent | C.ZitiRouterEvent | C.ZitiMfaAuthEvent + zid.Options.events = C.ZitiContextEvent | C.ZitiServiceEvent | C.ZitiRouterEvent | C.ZitiMfaAuthEvent | C.ZitiAPIEvent zid.Options.event_cb = C.ziti_event_cb(C.eventCB) ptr := unsafe.Pointer(zid) diff --git a/service/cziti/sdk.h b/service/cziti/sdk.h index 887221f9..5e1be218 100644 --- a/service/cziti/sdk.h +++ b/service/cziti/sdk.h @@ -67,6 +67,7 @@ void ziti_dump_go_to_log_cb(void *stringsBuffer, char *line); struct ziti_context_event* ziti_event_context_event(ziti_event_t *ev); struct ziti_router_event* ziti_event_router_event(ziti_event_t *ev); struct ziti_service_event* ziti_event_service_event(ziti_event_t *ev); +struct ziti_api_event* ziti_event_api_event(ziti_event_t *ev); ziti_service* ziti_service_array_get(ziti_service_array arr, int idx); diff --git a/service/debug.bat b/service/debug.bat index bb99fe88..1de89cdd 100644 --- a/service/debug.bat +++ b/service/debug.bat @@ -1 +1 @@ -cls & "c:\Program Files\JetBrains\GoLand 2020.1.1\plugins\go\lib\dlv\windows\dlv.exe" --listen=localhost:50000 --headless=true --api-version=2 --check-go-version=false --only-same-user=false exec ziti-tunnel.exe debug +cls & "c:\Program Files\JetBrains\GoLand 2021.3.1\plugins\go\lib\dlv\windows\dlv.exe" --listen=localhost:50000 --headless=true --api-version=2 --check-go-version=false --only-same-user=false exec ziti-tunnel.exe debug diff --git a/service/ziti-tunnel/api/api.go b/service/ziti-tunnel/api/api.go index ac94c876..14ce248d 100644 --- a/service/ziti-tunnel/api/api.go +++ b/service/ziti-tunnel/api/api.go @@ -36,6 +36,7 @@ type DesktopEdgeIface interface { BroadcastEvent(event interface{}) Close() UpdateMfa(fingerprint string, mfaEnabled bool, mfaNeeded bool) + UpdateAddress(configFile string, address string) } type DesktopEdgeManager interface { diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index e6bbf39c..78a6f49c 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -578,6 +578,61 @@ func (t *RuntimeState) UpdateMfa(fingerprint string, mfaEnabled bool, mfaNeeded } } +func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { + log.Debugf("request to update config file %s with new address: %s", configFile, newAddress) + + f, fe := ioutil.ReadFile(configFile) + if fe != nil { + log.Warnf("Could not update address for identity file: %s to newAddress: %s", configFile, newAddress) + return + } + c := idcfg.Config{} + err := json.Unmarshal(f, &c) + if err != nil { + log.Warnf("Could not update address for identity file: %s to newAddress: %s", configFile, newAddress) + return + } + + if strings.Compare(c.ZtAPI, newAddress) == 0 { + log.Debugf("not updating config for identity file %s. address already set to: %s", newAddress) + return + } + + newConfigFileName := configFile + ".address.update" + defer func() { + log.Debugf("removing original file: %s", newConfigFileName) + os.Remove(newConfigFileName) + }() + log.Debugf("renaming identity file %s as: %s", configFile, newConfigFileName) + _ = os.Rename(configFile, newConfigFileName) + + var newAddy string + if strings.HasPrefix(newAddress, "https://") { + newAddy = newAddress + } else { + newAddy = "https://" + newAddress + } + log.Errorf("writing identity file %s with new address from %s to %s", configFile, c.ZtAPI, c.ZtAPI) + c.ZtAPI = newAddy + + idFile, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) + defer idFile.Close() + if err != nil { + log.Warnf("An unexpected error has occurred while trying to update identity file %s with newAddress %s. %v", configFile, newAddress, err) + return + } + + w := bufio.NewWriter(bufio.NewWriter(idFile)) + enc := json.NewEncoder(w) + _ = enc.Encode(c) + _ = w.Flush() + + err = idFile.Close() + if err != nil { + log.Warnf("An unexpected error has occurred while closing the identity file %s with newAddress %s. %v", configFile, newAddress, err) + } +} + func (t *RuntimeState) SetNotified(fingerprint string, notified bool) { id := t.Find(fingerprint) diff --git a/version b/version index 8f874255..720c7384 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.10.14 +1.11.1 From b5ce4a224955291e0db1011b832af870cc67df9a Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 1 Feb 2022 20:35:09 -0500 Subject: [PATCH 2/6] minor log updates --- service/ziti-tunnel/service/state.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index 78a6f49c..b277a089 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -583,13 +583,13 @@ func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { f, fe := ioutil.ReadFile(configFile) if fe != nil { - log.Warnf("Could not update address for identity file: %s to newAddress: %s", configFile, newAddress) + log.Warnf("Could not read identity file: %s", configFile) return } c := idcfg.Config{} err := json.Unmarshal(f, &c) if err != nil { - log.Warnf("Could not update address for identity file: %s to newAddress: %s", configFile, newAddress) + log.Warnf("Could not unmarshal config file for identity file: %s to newAddress: %s", configFile, newAddress) return } @@ -612,7 +612,7 @@ func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { } else { newAddy = "https://" + newAddress } - log.Errorf("writing identity file %s with new address from %s to %s", configFile, c.ZtAPI, c.ZtAPI) + log.Infof("updating identity file %s with new address. chaning from %s to %s", configFile, c.ZtAPI, newAddy) c.ZtAPI = newAddy idFile, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) From c98c239989cf27cad594a0511b2ad77fbacd734d Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Tue, 1 Feb 2022 21:51:55 -0500 Subject: [PATCH 3/6] fix typo, small change to log msg --- service/ziti-tunnel/service/state.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index b277a089..bb415f99 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -600,7 +600,7 @@ func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { newConfigFileName := configFile + ".address.update" defer func() { - log.Debugf("removing original file: %s", newConfigFileName) + log.Debugf("removing original file after update: %s", newConfigFileName) os.Remove(newConfigFileName) }() log.Debugf("renaming identity file %s as: %s", configFile, newConfigFileName) @@ -612,7 +612,7 @@ func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { } else { newAddy = "https://" + newAddress } - log.Infof("updating identity file %s with new address. chaning from %s to %s", configFile, c.ZtAPI, newAddy) + log.Infof("updating identity file %s with new address. changing from %s to %s", configFile, c.ZtAPI, newAddy) c.ZtAPI = newAddy idFile, err := os.OpenFile(configFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) From 2cc3ff4558a040aa95c0b1ee41204502b4e05081 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 2 Feb 2022 09:35:58 -0500 Subject: [PATCH 4/6] always make an 'original' copy - in case we need it for whatever reason. remove originals when forgetting an identity --- service/ziti-tunnel/service/ipc.go | 20 ++++++++++++++++++++ service/ziti-tunnel/service/state.go | 27 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index 2c0b8941..fe18a37c 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -1079,6 +1079,26 @@ func removeIdentity(out *json.Encoder, fingerprint string) { log.Debugf("identity file removed: %s", id.Path()) } + //remove any ".original" file from the filesystem if there is one... + originalFileName := id.Path() + ".original" + _, err = os.Stat(originalFileName) + if err != nil { + if os.IsNotExist(err) { + //file does not exist. good... don't do anything... + } else { + // just ignore any other errors + } + } else { + // file does exist. remove it. + log.Debugf("removing .original file %s", originalFileName) + err = os.Remove(originalFileName) + if err != nil { + log.Warnf("could not remove file: %s", originalFileName) + } else { + log.Debugf("identity file removed: %s", originalFileName) + } + } + resp := dto.Response{Message: "success", Code: SUCCESS, Error: anyErrs, Payload: nil} respond(out, resp) // call shutdown some day id.CId.Shutdown() diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index bb415f99..61741d36 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -598,6 +598,12 @@ func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { return } + err = saveOriginalIdentity(configFile) + if err != nil { + log.Warnf("unexpected error when saving original identity. cannot change controller address. %v", err) + return + } + newConfigFileName := configFile + ".address.update" defer func() { log.Debugf("removing original file after update: %s", newConfigFileName) @@ -633,6 +639,27 @@ func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { } } +// if a change address header is ever processed - archive the original identity used. it will never be overwritten once created +// it will be deleted when the identity is forgotten +func saveOriginalIdentity(configFile string) error { + originalFileName := configFile + ".original" + + _, err := os.Stat(originalFileName) + if err != nil { + if os.IsNotExist(err) { + //file does not exist. good... + } else { + return err + } + } else { + log.Debugf("original identity already exists. not overwriting") + return nil + } + + log.Debugf("renaming original identity file from %s to %s", configFile, originalFileName) + return os.Rename(configFile, originalFileName) +} + func (t *RuntimeState) SetNotified(fingerprint string, notified bool) { id := t.Find(fingerprint) From 7e8b781d3dc89abbaed205b1c740a37a781853c2 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 2 Feb 2022 10:40:33 -0500 Subject: [PATCH 5/6] realized this if was useless, inverted the logic and removed the noop/useless block --- service/ziti-tunnel/service/ipc.go | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index fe18a37c..5b299c2d 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -1082,14 +1082,8 @@ func removeIdentity(out *json.Encoder, fingerprint string) { //remove any ".original" file from the filesystem if there is one... originalFileName := id.Path() + ".original" _, err = os.Stat(originalFileName) - if err != nil { - if os.IsNotExist(err) { - //file does not exist. good... don't do anything... - } else { - // just ignore any other errors - } - } else { - // file does exist. remove it. + if err == nil { + // file does exist and no other errors. remove it. log.Debugf("removing .original file %s", originalFileName) err = os.Remove(originalFileName) if err != nil { From 6316a73f07b55d7234a4632de9b7b33623cf0916 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 2 Feb 2022 10:41:56 -0500 Subject: [PATCH 6/6] change the name to more descriptive based on PR feedback --- service/cziti/sdk.go | 2 +- service/ziti-tunnel/api/api.go | 2 +- service/ziti-tunnel/service/state.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/service/cziti/sdk.go b/service/cziti/sdk.go index 1f470872..fd9a9945 100644 --- a/service/cziti/sdk.go +++ b/service/cziti/sdk.go @@ -761,7 +761,7 @@ func eventCB(ztx C.ziti_context, event *C.ziti_event_t) { apiEvent := C.ziti_event_api_event(event) newAddress := C.GoString(apiEvent.new_ctrl_address) cfgPath := C.GoString(zid.Options.config) - goapi.UpdateAddress(cfgPath, newAddress) + goapi.UpdateControllerAddress(cfgPath, newAddress) default: log.Infof("event %d not handled", event._type) } diff --git a/service/ziti-tunnel/api/api.go b/service/ziti-tunnel/api/api.go index 14ce248d..30b74862 100644 --- a/service/ziti-tunnel/api/api.go +++ b/service/ziti-tunnel/api/api.go @@ -36,7 +36,7 @@ type DesktopEdgeIface interface { BroadcastEvent(event interface{}) Close() UpdateMfa(fingerprint string, mfaEnabled bool, mfaNeeded bool) - UpdateAddress(configFile string, address string) + UpdateControllerAddress(configFile string, address string) } type DesktopEdgeManager interface { diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index 61741d36..52742ac3 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -578,7 +578,7 @@ func (t *RuntimeState) UpdateMfa(fingerprint string, mfaEnabled bool, mfaNeeded } } -func (t *RuntimeState) UpdateAddress(configFile string, newAddress string) { +func (t *RuntimeState) UpdateControllerAddress(configFile string, newAddress string) { log.Debugf("request to update config file %s with new address: %s", configFile, newAddress) f, fe := ioutil.ReadFile(configFile)