From 87aadb92694a3ccc0f037893d155ed6ee4e12d7c Mon Sep 17 00:00:00 2001 From: Shawn Carey Date: Mon, 5 Aug 2024 11:26:29 -0400 Subject: [PATCH 1/5] tsdk 2.0.0-alpha12 / csdk 2.0.0-alpha10 / tlsuv 0.31.2 --- deps/ziti-tunnel-sdk-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/ziti-tunnel-sdk-c b/deps/ziti-tunnel-sdk-c index 6eae8e8..8af32f5 160000 --- a/deps/ziti-tunnel-sdk-c +++ b/deps/ziti-tunnel-sdk-c @@ -1 +1 @@ -Subproject commit 6eae8e8abd656c165695c41e48ffa56c2699d25b +Subproject commit 8af32f5d4b5fa67999d3202536f77fbbbdb7d223 From 0c0e556420401cee8f48bd867ac713757e61641c Mon Sep 17 00:00:00 2001 From: Shawn Carey Date: Mon, 5 Aug 2024 11:52:44 -0400 Subject: [PATCH 2/5] csdk api updates --- lib/ZitiEnroller.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ZitiEnroller.swift b/lib/ZitiEnroller.swift index 6b28705..7b4d3c9 100644 --- a/lib/ZitiEnroller.swift +++ b/lib/ZitiEnroller.swift @@ -129,7 +129,7 @@ import CZitiPrivate var enroll_opts = ziti_enroll_opts(jwt: enrollData.pointee.jwtFile_c, enroll_key: enrollData.pointee.privatePem_c, - enroll_cert: nil, enroll_name: nil, jwt_content: nil) + enroll_cert: nil, enroll_name: nil, jwt_content: nil, use_keychain: false) let status = ziti_enroll(&enroll_opts, loop, ZitiEnroller.on_enroll, enrollData) guard status == ZITI_OK else { let errStr = String(cString: ziti_errorstr(status)) From 21b1b5d6a5cd0863f2bbf47368b89f058c8f013f Mon Sep 17 00:00:00 2001 From: Shawn Carey Date: Mon, 5 Aug 2024 12:22:32 -0400 Subject: [PATCH 3/5] update vcpkg baseline. install auto tools. --- .github/workflows/CI.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 9d20a5b..fa7d8a2 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -34,9 +34,14 @@ jobs: with: xcode-version: '15.2' + - name: macOS tools + if: runner.os == 'macOS' + shell: bash + run: brew install autoconf autoconf-archive automake pkg-config + - uses: lukka/run-vcpkg@v11 with: - vcpkgGitCommitId: 'fba75d09065fcc76a25dcf386b1d00d33f5175af' + vcpkgGitCommitId: '1de2026f28ead93ff1773e6e680387643e914ea1' - name: ${{ matrix.spec.name }} env: From 0993aca2ad4908980fcd81d04eaf646b83de828b Mon Sep 17 00:00:00 2001 From: Shawn Carey Date: Tue, 6 Aug 2024 08:27:40 -0400 Subject: [PATCH 4/5] mirror branch name when publishing to ziti-sdk-swift-dist --- .github/workflows/publish.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 10097ff..a73b58c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,15 +14,15 @@ jobs: - name: Get Release id: get_release run: | - tag_name=$(gh release list --exclude-drafts -L1 --json tagName --jq '.[0].tagName') echo "tag_name=${tag_name}" | tee -a $GITHUB_OUTPUT - tag_suffix=$(echo -n "${tag_name}" | cut -s -d '-' -f 2-) - dist_branch=$(echo -n ${tag_suffix:-main}) + dist_branch=$(echo ${target_commitsh} | awk -F / '{print $NF}') echo "dist_branch=${dist_branch}" | tee -a $GITHUB_OUTPUT - gh_pages_branch="gh-pages${tag_suffix:+-$tag_suffix}" + gh_pages_branch="gh-pages$([ "${dist_branch}" != "main" ] && echo "-${dist_branch}")" echo "gh_pages_branch=${gh_pages_branch}" | tee -a $GITHUB_OUTPUT env: GITHUB_TOKEN: ${{ github.token }} + tag_name: ${{ github.event.release.tag_name }} + target_commitsh: ${{ github.event.release.target_commitish }} - name: Download xcframework run: | From 77906030f9f876cebec9e34548c43728d5d9bc96 Mon Sep 17 00:00:00 2001 From: Shawn Carey Date: Fri, 30 Aug 2024 09:06:49 -0400 Subject: [PATCH 5/5] conform to tsdk 2.0.0-alpha17 / csdk 2.0.0-alpha18 --- deps/ziti-tunnel-sdk-c | 2 +- lib/Ziti-Bridging-Header.h | 3 + lib/Ziti.swift | 4 +- lib/ZitiEvent.swift | 134 +++++++++++++++++++++++++++++-------- lib/ZitiMfaAuthQuery.swift | 4 +- lib/ZitiPostureQuery.swift | 4 +- lib/ZitiService.swift | 2 +- lib/ZitiTunnel.swift | 6 +- lib/ZitiTunnelEvent.swift | 4 +- lib/ziti.c | 13 ++++ 10 files changed, 138 insertions(+), 38 deletions(-) diff --git a/deps/ziti-tunnel-sdk-c b/deps/ziti-tunnel-sdk-c index 8af32f5..7614153 160000 --- a/deps/ziti-tunnel-sdk-c +++ b/deps/ziti-tunnel-sdk-c @@ -1 +1 @@ -Subproject commit 8af32f5d4b5fa67999d3202536f77fbbbdb7d223 +Subproject commit 7614153ad23d3c60cd4f2695d1a4163399528a5d diff --git a/lib/Ziti-Bridging-Header.h b/lib/Ziti-Bridging-Header.h index 877096d..5bfcf3d 100644 --- a/lib/Ziti-Bridging-Header.h +++ b/lib/Ziti-Bridging-Header.h @@ -38,3 +38,6 @@ void freeStringArray(char **arr); char *copyString(const char *str); void freeString(char *str); + +tunnel_upstream_dns_array createUpstreamDnsArray(uint8_t size); +void addUpstreamDns(tunnel_upstream_dns_array upstreams, const char *host, uint16_t port); diff --git a/lib/Ziti.swift b/lib/Ziti.swift index 732c500..b3fd36e 100644 --- a/lib/Ziti.swift +++ b/lib/Ziti.swift @@ -433,7 +433,7 @@ import CZitiPrivate var zitiCfg = ziti_config( controller_url: ctrlPtr, controllers: ctrls, - id: ziti_id_cfg(cert: certPEMPtr, key: privKeyPEMPtr, ca: caPEMPtr), + id: ziti_id_cfg(cert: certPEMPtr, key: privKeyPEMPtr, ca: caPEMPtr, oidc: nil), cfg_source: nil) // todo what is cfg_source? var zitiStatus = ziti_context_init(&self.ztx, &zitiCfg) @@ -464,7 +464,7 @@ import CZitiPrivate pq_process_cb: postureChecks?.processQuery != nil ? Ziti.onProcessQuery : nil, pq_domain_cb: postureChecks?.domainQuery != nil ? Ziti.onDomainQuery : nil, app_ctx: self.toVoidPtr(), - events: ZitiContextEvent.rawValue | ZitiRouterEvent.rawValue | ZitiServiceEvent.rawValue | ZitiMfaAuthEvent.rawValue | ZitiAPIEvent.rawValue, + events: ZitiContextEvent.rawValue | ZitiRouterEvent.rawValue | ZitiServiceEvent.rawValue | ZitiAuthEvent.rawValue | ZitiAPIEvent.rawValue, event_cb: Ziti.onEvent) zitiStatus = ziti_context_set_options(self.ztx, &zitiOpts) diff --git a/lib/ZitiEvent.swift b/lib/ZitiEvent.swift index 50b6f09..c51e084 100644 --- a/lib/ZitiEvent.swift +++ b/lib/ZitiEvent.swift @@ -39,7 +39,7 @@ import CZitiPrivate case Service = 0x04 // ZitiServiceEvent.rawValue /// Indicates an `MfaAuthEvent` - case MfaAuth = 0x08 // ZitiMfaAuthEvent.rawValue + case Auth = 0x08 // ZitiAuthEvent.rawValue /// Indicates an `ApiEvent` case ApiEvent = 0x10 // ZitiApiEvent.rawValue @@ -58,8 +58,8 @@ import CZitiPrivate /// Indicates `ServiceEvent` case .Service: return ".Service" - /// Indicates `MfaAuthEvent` - case .MfaAuth: return ".MfaAuth" + /// Indicates `AuthEvent` + case .Auth: return ".Auth" /// Indicates `ApiEvent` case .ApiEvent: return ".ApiEvent" @@ -164,18 +164,97 @@ import CZitiPrivate } } } - - /// Encapsulation of Ziti SDK C's MFA Auth Event - @objc public class MfaAuthEvent : NSObject { - - /// The authentication query - @objc public var mfaAuthQuery:ZitiMfaAuthQuery? - init(_ cEvent:ziti_mfa_auth_event) { - if cEvent.auth_query_mfa != nil { - mfaAuthQuery = ZitiMfaAuthQuery(cEvent.auth_query_mfa) + + /// Enumeration of possible authentication actions + @objc public enum AuthAction : UInt32 { + /// Request for MFA code + case PromptTotp + + /// Request for HSM/TPM key pin (not yet implemented) + case PromptPin + + /// Request for app to launch external program/browser that can authenticate with url in [detail] field of auth event + case LoginExternal + + case Unknown + + init(_ action:ziti_auth_action) { + switch action { + case ziti_auth_prompt_totp: self = .PromptTotp + case ziti_auth_prompt_pin: self = .PromptPin + case ziti_auth_login_external: self = .LoginExternal + default: self = .Unknown + } + } + + /// Returns string representation of AuthAction + public var debug: String { + switch self { + case .PromptTotp: return ".PromptTotp" + case .PromptPin: return ".PromptPin" + case .LoginExternal: return ".LoginExternal" + case .Unknown: return ".Unknown" + @unknown default: return "unknown \(self.rawValue)" } } } + + /// Encapsualtion of Ziti SDK C's JWTSigner + @objc public class JwtSigner : NSObject { + /// ID + @objc public let id:String + + /// Name + @objc public let name:String + + /// Enabled + @objc public let enabled:Bool + + /// Provider URL + @objc public let providerUrl:String + + /// Client ID + @objc public let clientId:String + + /// Audience + @objc public let audience:String + + /// Claim + @objc public let claim:String + + init(_ cSigner:ziti_jwt_signer) { + id = cSigner.name != nil ? String(cString: cSigner.id) : "" + name = cSigner.name != nil ? String(cString: cSigner.name) : "" + enabled = cSigner.enabled + providerUrl = cSigner.provider_url != nil ? String(cString: cSigner.provider_url) : "" + clientId = cSigner.client_id != nil ? String(cString: cSigner.client_id) : "" + audience = cSigner.audience != nil ? String(cString: cSigner.audience) : "" + claim = cSigner.claim != nil ? String(cString: cSigner.claim) : "" + } + } + + /// Encapsulation of Ziti SDK C's Auth Event + @objc public class AuthEvent : NSObject { + + /// The authentication action + @objc public var action:AuthAction + + /// The authentication type + @objc public var type:String + + /// The authentication detail + @objc public var detail:String + + /// Authentication providers + @objc public var providers:Array + + init(_ cEvent:ziti_auth_event) { + action = AuthAction(cEvent.action) + type = cEvent.type != nil ? String(cString: cEvent.type) : "" + detail = cEvent.detail != nil ? String(cString: cEvent.detail) : "" + providers = [] // todo populate + } + } /// Encapsulation of Ziti SDK C's API Event @objc public class ApiEvent : NSObject { @@ -214,7 +293,7 @@ import CZitiPrivate @objc public var serviceEvent:ServiceEvent? /// Populated based on event `type` - @objc public var mfaAuthEvent:MfaAuthEvent? + @objc public var authEvent:AuthEvent? /// Populated based on event `type` @objc public var apiEvent:ApiEvent? @@ -228,8 +307,8 @@ import CZitiPrivate serviceEvent = ServiceEvent(cEvent.pointee.service) } else if type == .Router { routerEvent = RouterEvent(cEvent.pointee.router) - } else if type == .MfaAuth { - mfaAuthEvent = MfaAuthEvent(cEvent.pointee.mfa_auth_event) + } else if type == .Auth { + authEvent = AuthEvent(cEvent.pointee.auth) } else if type == .ApiEvent { apiEvent = ApiEvent(cEvent.pointee.api) } else { @@ -260,18 +339,11 @@ import CZitiPrivate str += " added: (\(e.added.count))\n\(ZitiEvent.svcArrToStr(e.added))" } - if let e = mfaAuthEvent { - if let mfaAuthQuery = e.mfaAuthQuery { - str += " provider: \(mfaAuthQuery.provider ?? "nil")\n" - str += " typeId: \(mfaAuthQuery.typeId ?? "nil")\n" - str += " httpMethod: \(mfaAuthQuery.httpMethod ?? "nil")\n" - str += " httpUrl: \(mfaAuthQuery.httpUrl ?? "nil")\n" - str += " minLength: \(mfaAuthQuery.minLength ?? -1)\n" - str += " maxLength: \(mfaAuthQuery.maxLength ?? -1)\n" - str += " format: \(mfaAuthQuery.format ?? "nil")\n" - } else { - str += " mfaAuthQuery: nil\n" - } + if let e = authEvent { + str += " action: \(e.type)\n" + str += " type: \(e.type)\n" + str += " detail: \(e.detail)\n" + str += " providers: (\(e.providers.count))\n\(ZitiEvent.jwtSignerArrToStr(e.providers))" } if let e = apiEvent { @@ -295,4 +367,12 @@ import CZitiPrivate } return str } + + static func jwtSignerArrToStr(_ arr:[JwtSigner]) -> String { + var str = "" + for (i, signer) in arr.enumerated() { + str += " \(i):\(signer.description)\n" + } + return str + } } diff --git a/lib/ZitiMfaAuthQuery.swift b/lib/ZitiMfaAuthQuery.swift index 74217ba..475e88d 100644 --- a/lib/ZitiMfaAuthQuery.swift +++ b/lib/ZitiMfaAuthQuery.swift @@ -34,10 +34,10 @@ import CZitiPrivate public var httpUrl:String? /// minimum length - public var minLength:Int32? + public var minLength:Int64? /// maximum length - public var maxLength:Int32? + public var maxLength:Int64? /// expected format public var format:String? diff --git a/lib/ZitiPostureQuery.swift b/lib/ZitiPostureQuery.swift index e319e4f..2986800 100644 --- a/lib/ZitiPostureQuery.swift +++ b/lib/ZitiPostureQuery.swift @@ -31,10 +31,10 @@ import CZitiPrivate public var id:String? /// Timeout in seconds (if specified, -1 if not applicable) - public var timeout:Int32? + public var timeout:Int64? /// Timeout remaining (if applicable, otherwise -1) - public var timeoutRemaining:Int32? + public var timeoutRemaining:Int64? init(_ cPQ:UnsafeMutablePointer) { isPassing = cPQ.pointee.is_passing diff --git a/lib/ZitiService.swift b/lib/ZitiService.swift index ca50b23..246c4df 100644 --- a/lib/ZitiService.swift +++ b/lib/ZitiService.swift @@ -43,7 +43,7 @@ import CZitiPrivate public var encrypted:Bool? /// Service permisions (e.g., DIAL and/or BIND) - public var permFlags:Int32? + public var permFlags:Int64? /// Listing of posture query sets public var postureQuerySets:[ZitiPostureQuerySet]? diff --git a/lib/ZitiTunnel.swift b/lib/ZitiTunnel.swift index 1d86acd..7dc9be1 100644 --- a/lib/ZitiTunnel.swift +++ b/lib/ZitiTunnel.swift @@ -156,7 +156,11 @@ public class ZitiTunnel : NSObject, ZitiUnretained { upPort = UInt16(parts[1]) ?? upPort } log.debug("upStreamDNS=\(upDNS), port=\(upPort)") - return ziti_dns_set_upstream(loopPtr.loop, upDNS.cString(using: .utf8), upPort) + var upstreams:tunnel_upstream_dns_array? = createUpstreamDnsArray(1) + addUpstreamDns(upstreams, upDNS, upPort) + var rc = ziti_dns_set_upstream(loopPtr.loop, upstreams) + free_tunnel_upstream_dns_array(&upstreams) + return rc } /// Perform on operation on the uv_loop managed by this class diff --git a/lib/ZitiTunnelEvent.swift b/lib/ZitiTunnelEvent.swift index c037392..74a0661 100644 --- a/lib/ZitiTunnelEvent.swift +++ b/lib/ZitiTunnelEvent.swift @@ -56,7 +56,7 @@ import CZitiPrivate public var controller:String = "" /// Controller event code - public var code:Int32 + public var code:Int64 init(_ ziti:Ziti, _ evt:UnsafePointer) { self.code = evt.pointee.code @@ -145,7 +145,7 @@ import CZitiPrivate public var recovery_codes:[String] /// MFA authentication code - public var code:Int32 + public var code:Int64 init(_ ziti:Ziti, _ evt:UnsafePointer) { self.operationType = MfaStatus(evt.pointee.operation_type) diff --git a/lib/ziti.c b/lib/ziti.c index ca4ca52..e434096 100644 --- a/lib/ziti.c +++ b/lib/ziti.c @@ -87,3 +87,16 @@ char *copyString(const char *str) { void freeString(char *str) { if (str) free(str); } + +tunnel_upstream_dns_array createUpstreamDnsArray(uint8_t size) { + return calloc(size + 1, sizeof(tunnel_upstream_dns *)); +} + +void addUpstreamDns(tunnel_upstream_dns_array upstreams, const char *host, uint16_t port) { + int i = 0; + for (i = 0; upstreams[i] != NULL; i++); + tunnel_upstream_dns *upstream = calloc(1, sizeof(tunnel_upstream_dns)); + upstream->host = strdup(host); + upstream->port = port; + upstreams[i] = upstream; +}