diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index f62c63f7..8d780bad 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -1,4 +1,4 @@ -me-template: 'v$RESOLVED_VERSION' +name-template: 'v$RESOLVED_VERSION' tag-template: 'v$RESOLVED_VERSION' categories: - title: 'Features' @@ -10,11 +10,11 @@ categories: - 'fix' - 'bugfix' - 'bug' - - title: 'í·°Maintenance' + - title: 'Maintenance' label: 'chore' - title: 'Dependencies' label: 'dependencies' -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-template: '- $TITLE [#$NUMBER]' change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. version-resolver: major: @@ -27,6 +27,8 @@ version-resolver: labels: - 'patch' default: patch +exclude-labels: + - 'changelog-ignore' template: | ## Changes $CHANGES diff --git a/.github/workflows/installer.build.yml b/.github/workflows/installer.build.yml new file mode 100644 index 00000000..452bb490 --- /dev/null +++ b/.github/workflows/installer.build.yml @@ -0,0 +1,55 @@ +name: Build Installer + +on: + push: + branches: + - master + - 'release-*' + +env: + BUILD_CONFIG: "Release" + BUILDNUMBER: ${{github.run_number}} + +jobs: + build: + name: Build the Ziti Desktop Edge for Windows Installer Package + runs-on: windows-latest + env: + SOME_KEY: ${{ secrets.SOME_KEY }} + ADV_INST_KEY: ${{ secrets.ADV_INST_KEY }} + + steps: + - uses: actions/checkout@master + - uses: microsoft/setup-msbuild@v1 + - name: Set GIT_BRANCH and add GOPATH/bin to PATH + run: | + echo ("::set-env name=GIT_BRANCH::" + $env:GITHUB_REF.replace('refs/heads/', '')) + echo "::set-env name=GOPATH::$(go env GOPATH)" + echo "::add-path::$(go env GOPATH)/bin" + - name: Setup secrets + run: | + echo "${env:SOME_KEY}" > WinSign.b64 + echo "${env:ADV_INST_KEY}" > ADV_INST_KEY.key + C:\Windows\System32\certutil.exe -decode WinSign.b64 Installer/WinSign.p12 + - name: Trying to run choco install. + run: Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) + - name: "Install Choco needs: advanced-installer wixtoolset zip ninja" + run: choco install advanced-installer wixtoolset zip ninja --yes + - name: Build the Service + run: service/publish.bat + - name: Restore nuget packages + run: nuget restore ZitiDesktopEdge.sln + - shell: pwsh + name: Register Advanced Installer + run: | + $key=(Get-Content .\ADV_INST_KEY.key) + .\Installer\reg.bat $key + - name: Build UI and Assemble Installer + run: powershell -File .\Installer\build.ps1 + - name: Upload installer onto job + uses: actions/upload-artifact@v2 + with: + name: ZitiDesktopEdgeClient + path: "Installer/Output/Ziti Desktop Edge Client-*.exe" + env: + version: Get-Content .\version diff --git a/.gitignore b/.gitignore index 3365cc33..9fca1e12 100644 --- a/.gitignore +++ b/.gitignore @@ -265,3 +265,4 @@ ziti-tunnel-win.zip service/deps service/ziti.dll service/libuv.dll +ziti-tunnel-service.zip diff --git a/.travis.yml b/.travis.yml index bebe0583..9bde03f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,12 +8,16 @@ go: os: - windows -#branches: //first try at only building PR or branch push - updated to the first if on line 1 above -# only: +# first try at only building PR or branch push - updated to the first if on line 1 above +#branches: +# except: +# - installer +## only: # - "master" install: - - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install -y zip ninja; fi + - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then choco install -y zip ninja --no-progress; fi + - PowerShell -Command 'Set-ExecutionPolicy -ExecutionPolicy RemoteSigned' before_script: - export GIT_BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi) diff --git a/DesktopEdge/IdentityDetails.xaml.cs b/DesktopEdge/IdentityDetails.xaml.cs index b12083c9..c7183a37 100644 --- a/DesktopEdge/IdentityDetails.xaml.cs +++ b/DesktopEdge/IdentityDetails.xaml.cs @@ -85,10 +85,10 @@ namespace ZitiDesktopEdge { editor.IsLocked = true; ServiceList.Children.Add(editor); } - int sHeight = 36 * _identity.Services.Count; - if (sHeight > 200) sHeight = 200; - Debug.WriteLine("Height: " + ServiceRow.Height.Value.ToString()); - ServiceRow.Height = new GridLength((double)sHeight); + double newHeight = Application.Current.MainWindow.ActualHeight - 360; + ServiceRow.Height = new GridLength((double)newHeight); + MainDetailScroll.MaxHeight = newHeight; + MainDetailScroll.Height = newHeight; MainDetailScroll.Visibility = Visibility.Visible; ServiceTitle.Content = _identity.Services.Count + " SERVICES"; } else { diff --git a/DesktopEdge/MainWindow.xaml.cs b/DesktopEdge/MainWindow.xaml.cs index ec61e71c..7528db6c 100644 --- a/DesktopEdge/MainWindow.xaml.cs +++ b/DesktopEdge/MainWindow.xaml.cs @@ -74,11 +74,13 @@ namespace ZitiDesktopEdge { } private void MainWindow_Deactivated(object sender, EventArgs e) { + if (this._isAttached) { #if DEBUG Debug.WriteLine("debug is enabled - windows pinned"); #else this.Visibility = Visibility.Collapsed; #endif + } } private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { @@ -528,7 +530,7 @@ namespace ZitiDesktopEdge { } private void MainUI_Deactivated(object sender, EventArgs e) { - if (UIModel.HideOnLostFocus) { + if (this._isAttached) { #if DEBUG Debug.WriteLine("debug is enabled - windows pinned"); #else diff --git a/DesktopEdge/Properties/AssemblyInfo.cs b/DesktopEdge/Properties/AssemblyInfo.cs index 31ca282c..dc5e6c1d 100644 --- a/DesktopEdge/Properties/AssemblyInfo.cs +++ b/DesktopEdge/Properties/AssemblyInfo.cs @@ -12,7 +12,7 @@ using System.Windows; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Ziti Desktop Edge")] -[assembly: AssemblyCopyright("Copyright NetFoundry © 2020")] +[assembly: AssemblyCopyright("Copyright NetFoundry © 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -51,5 +51,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2.8.0")] -[assembly: AssemblyFileVersion("1.2.8.0")] +[assembly: AssemblyVersion("1.2.11.0")] +[assembly: AssemblyFileVersion("1.2.11.0")] diff --git a/Installer/.gitignore b/Installer/.gitignore index 52b1a45c..5edd8264 100644 --- a/Installer/.gitignore +++ b/Installer/.gitignore @@ -1,4 +1,6 @@ ZitiDesktopEdge-cache Output WinSign.p12 -*.p12 \ No newline at end of file +*.p12 +build/ +ziti-tunnel-service.zip diff --git a/Installer/ZitiDesktopEdge.aip b/Installer/ZitiDesktopEdge.aip index d6773ad3..7d48a44c 100644 --- a/Installer/ZitiDesktopEdge.aip +++ b/Installer/ZitiDesktopEdge.aip @@ -1,4 +1,4 @@ - + @@ -25,7 +25,7 @@ - + @@ -70,11 +70,11 @@ - - - - - + + + + + @@ -100,7 +100,7 @@ - + @@ -292,3 +292,14 @@ + + + + + + + + + + + diff --git a/Installer/build.ps1 b/Installer/build.ps1 new file mode 100644 index 00000000..dce113bc --- /dev/null +++ b/Installer/build.ps1 @@ -0,0 +1,70 @@ +echo "========================== build.ps1 begins ==========================" +echo "Cleaning previous build folder if it exists" +rm .\build -r -fo -ErrorAction Ignore + +$invocation = (Get-Variable MyInvocation).Value +$scriptPath = Split-Path $invocation.MyCommand.Path +${scriptPath} + +$x=[xml] @" +$((Invoke-WebRequest https://netfoundry.jfrog.io/artifactory/ziti-maven-snapshot/ziti-tunnel-win/amd64/windows/ziti-tunnel-win/maven-metadata.xml).Content) +"@ + +echo "the branch is $env:GIT_BRANCH" + +$branch = git rev-parse --abbrev-ref HEAD + +if ("$branch" -ne 'master') { + #if the git command to get the branch fails - this is 'not master' use the 'latest' - else fetch the 'release' + $serviceVersion = $x.metadata.versioning.latest +} +else { + $serviceVersion = $x.metadata.versioning.release +} +echo "service version is: $serviceVersion" +$installerVersion=(Get-Content -Path .\version) + +$zipUrl = "https://netfoundry.jfrog.io/artifactory/ziti-maven-snapshot/ziti-tunnel-win/amd64/windows/ziti-tunnel-win/${serviceVersion}/ziti-tunnel-win-${serviceVersion}.zip" + +echo "Downloading zip file " +echo " from: $zipUrl" + +$ProgressPreference = 'SilentlyContinue' +$timeTaken = Measure-Command -Expression { + Invoke-WebRequest $zipUrl -OutFile ziti-tunnel-service.zip +} + +$milliseconds = $timeTaken.TotalMilliseconds +echo " time to download: $milliseconds" +echo "" +echo "unzipping ziti-tunnel-service.zip to build\service\" + +$ProgressPreference = 'Continue' + +Expand-Archive -Verbose -Force -LiteralPath ziti-tunnel-service.zip "${scriptPath}\build\service\" + +Push-Location ${scriptPath}\.. +echo "Updating the version for UI and Installer" +.\update-versions.ps1 + +echo "Building the UI" +#msbuild DesktopEdge\ZitiDesktopEdge.csproj /property:Configuration=Release +msbuild ZitiDesktopEdge.sln /property:Configuration=Release + +echo "Building the Wintun installer" +msbuild ZitiWintunInstaller.sln /p:configuration=Release + +Pop-Location + +$ADVINST = "C:\Program Files (x86)\Caphyon\Advanced Installer 17.5\bin\x86\AdvancedInstaller.com" +$ADVPROJECT = "${scriptPath}\ZitiDesktopEdge.aip" + +$action = '/SetVersion' +echo "issuing $ADVINST /edit $ADVPROJECT $action $installerVersion (service version: $serviceVersion) - see https://www.advancedinstaller.com/user-guide/set-version.html" +& $ADVINST /edit $ADVPROJECT $action $installerVersion + +$action = '/build' +echo "Assembling installer using AdvancedInstaller at: $ADVINST $action $ADVPROJECT" +& $ADVINST $action $ADVPROJECT + +echo "========================== build.ps1 competed ==========================" \ No newline at end of file diff --git a/Installer/reg.bat b/Installer/reg.bat new file mode 100644 index 00000000..7dc8dbac --- /dev/null +++ b/Installer/reg.bat @@ -0,0 +1 @@ +"C:\Program Files (x86)\Caphyon\Advanced Installer 17.5\bin\x86\AdvancedInstaller.com" /register %1 \ No newline at end of file diff --git a/release-notes-service.md b/release-notes-service.md deleted file mode 100644 index 1dad7035..00000000 --- a/release-notes-service.md +++ /dev/null @@ -1,119 +0,0 @@ -These release notes will catalog the changes in the Windows service. -For UI changes or installer changes see [release-notes.md]() - -# Release 0.0.30 - -* What's New - - * Continually improved logging - * changed ip from 169.254.0.0/16 to 100.64.0.0/10 - * [#120](https://github.com/openziti/desktop-edge-win/issues/120) - Allow UI/client to get and set log level dynamically via ipc - -* Bug fixes - - * [#116](https://github.com/openziti/desktop-edge-win/issues/116) - Removes information from the config that wasn't needed in config.json - -# Release 0.0.29 - -* What's New - - * Continually improved logging - * Add support for 'verbose' logging along with error, warn, info, debug, trace - -* Bug fixes - - * [#123](https://github.com/openziti/desktop-edge-win/issues/123) - ConnectionSpecificDomains cause DNS lookup failures - * [#117](https://github.com/openziti/desktop-edge-win/issues/117) - TLD were not resolving properly - fixed in 0.0.28 but marking resolved in 0.0.29 - -# Release 0.0.28 - -* What's New - - * Continually improved logging - * Better DNS removal when services are no longer available or when an identity is removed - -* Bug fixes - - * [#106](https://github.com/openziti/desktop-edge-win/issues/106) - DNS stops responding when changing wireless networks - * [#121](https://github.com/openziti/desktop-edge-win/issues/121) - DNS queries take a long time after a computer wakes from sleep - -# Release 0.0.27 - -* Bug fixes - - * [#119](https://github.com/openziti/desktop-edge-win/issues/119) - Service would not start when IPv6 was disabled via the Windows registry - -# Release 0.0.24 - -* What's New - - * [#94](https://github.com/openziti/desktop-edge-win/issues/94) - Added support for 'hosted' services - -* Bug fixes - - * [#102](https://github.com/openziti/desktop-edge-win/pull/102) - DNS requests with "connection-specific local domain" would not resolve - -# Release 0.0.21-23 - nothing captured - -# Release 0.0.20 - -* What's New - - * Nothing yet - -* Bug fixes - - * [#85](https://github.com/openziti/desktop-edge-win/issues/85) - buffer DNS messages and panic/recover properly when network changes happen - -# Release 0.0.19 - -* What's New - - * Nothing yet - -* Bug fixes - - * [#82](https://github.com/openziti/desktop-edge-win/issues/82) - MTU was no longer sent to UI correctly - * [#86](https://github.com/openziti/desktop-edge-win/issues/86) - Inconsistent treatment of DNS requests - all requests will be treated as absolute going forward - * [#90](https://github.com/openziti/desktop-edge-win/issues/90) - UI will not reconnect to service if started before service - -# Release 0.0.18 - -* What's New - - * [#70](https://github.com/openziti/desktop-edge-win/issues/70) - Version added to api to report when model changes occur - -* Bug fixes - - * [#69](https://github.com/openziti/desktop-edge-win/issues/69) - reference counting for identities with access to the same service - -# Release 0.0.17 - -* What's New - - * [#70](https://github.com/openziti/desktop-edge-win/issues/70) - added api ApiVersion to TunnelStatusEvent - * [#71](https://github.com/openziti/desktop-edge-win/issues/71) - add .log to rolled over log files - -* Bug fixes - - * [#59](https://github.com/openziti/desktop-edge-win/issues/59) - too many services blocked service from accepting connections from the UI - * [#61](https://github.com/openziti/desktop-edge-win/issues/61) - identity shutdown needs to be on the uv loop (issue with forgetting identities) - * [#63](https://github.com/openziti/desktop-edge-win/issues/63) - when service restarts and UI reconnects clear identities and let the service repopulate the UI - * [#67](https://github.com/openziti/desktop-edge-win/issues/67) - set the MTU based on the value reported from the interface - -# Release 0.0.16 - -- tracking lost - -# Release 0.0.15 - -* What's New - -* Bug fixes - * [#51](https://github.com/openziti/desktop-edge-win/issues/51) - cziti log would never roll over. - now the cziti log rolls daily with a maximum of seven (7) log files - -# All versions prior to 0.0.15 - -Changelog tracking began with 0.0.15 - all previous changes were not tracked. If interested please -review the commit history. diff --git a/release-notes.md b/release-notes.md index 12b27a73..ab473b65 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,13 +1,38 @@ -These release notes will try to cover the changes made for the installer. For changes made -to the Windows service see [release-notes-service.md]() +# Release 1.2.11 + +* What's New + + * [#135](https://github.com/openziti/desktop-edge-win/pull/135) - Support added for IPv4 intercepting. + Services can now be created for any IPv4 address. + * [#123](https://github.com/openziti/desktop-edge-win/pull/123) - Windows can add ConnectionSpecificDomains + to DNS requests where no period (.) is in the DNS request such as "web-page" or "my-service". + These requests would not resolve properly because they would be received as "web-page.myConnectionSpecificDomain". + This now works correctly. + * [#131](https://github.com/openziti/desktop-edge-win/pull/131) - Installer added to GitHub Actions build. + +* Bug Fixes + + * [#130](https://github.com/openziti/desktop-edge-win/pull/130) - Detection of new release was inconsistent. + * [#129](https://github.com/openziti/desktop-edge-win/pull/129) - DNS entry was not removed when service was deleted. + +# Release 1.2.9 + +* What's New + + * adds support for Ziti-provided end to end encryption + * upgrades the Ziti Desktop Edge Service to version 0.0.30 + * the log level can now be changed from the UI by going to Advanced Settings -> Set Logging Level + * the config file has been slimmed + * the name used to start/stop the Ziti Desktop Edge Service has been made much more convenient. + Now you can start and stop the service with: `net start|stop ziti` (this is the change that + necessitates removing and reinstalling the application during upgrade from previous versions) # Release 1.2.6 * What's New * 'About' updated to reflect actual service version - * Added ability to set the log level of the service dynamically through Advanced Setttings - * + * Added ability to set the log level of the service dynamically through Advanced Settings * Bug fixes @@ -22,3 +47,120 @@ to the Windows service see [release-notes-service.md]() * Bug fixes * [#102](https://github.com/openziti/desktop-edge-win/pull/102) - DNS requests with "connection-specific local domain" would not resolve + +# Release 0.0.30 + +* What's New + + * Continually improved logging + * changed ip from 169.254.0.0/16 to 100.64.0.0/10 + * [#120](https://github.com/openziti/desktop-edge-win/issues/120) - Allow UI/client to get and set log level dynamically via ipc + +* Bug fixes + + * [#116](https://github.com/openziti/desktop-edge-win/issues/116) - Removes information from the config that wasn't needed in config.json + +# Release 0.0.29 + +* What's New + + * Continually improved logging + * Add support for 'verbose' logging along with error, warn, info, debug, trace + +* Bug fixes + + * [#123](https://github.com/openziti/desktop-edge-win/issues/123) - ConnectionSpecificDomains cause DNS lookup failures + * [#117](https://github.com/openziti/desktop-edge-win/issues/117) - TLD were not resolving properly - fixed in 0.0.28 but marking resolved in 0.0.29 + +# Release 0.0.28 + +* What's New + + * Continually improved logging + * Better DNS removal when services are no longer available or when an identity is removed + +* Bug fixes + + * [#106](https://github.com/openziti/desktop-edge-win/issues/106) - DNS stops responding when changing wireless networks + * [#121](https://github.com/openziti/desktop-edge-win/issues/121) - DNS queries take a long time after a computer wakes from sleep + +# Release 0.0.27 + +* Bug fixes + + * [#119](https://github.com/openziti/desktop-edge-win/issues/119) - Service would not start when IPv6 was disabled via the Windows registry + +# Release 0.0.24 + +* What's New + + * [#94](https://github.com/openziti/desktop-edge-win/issues/94) - Added support for 'hosted' services + +* Bug fixes + + * [#102](https://github.com/openziti/desktop-edge-win/pull/102) - DNS requests with "connection-specific local domain" would not resolve + +# Release 0.0.21-23 - nothing captured + +# Release 0.0.20 + +* What's New + + * Nothing yet + +* Bug fixes + + * [#85](https://github.com/openziti/desktop-edge-win/issues/85) - buffer DNS messages and panic/recover properly when network changes happen + +# Release 0.0.19 + +* What's New + + * Nothing yet + +* Bug fixes + + * [#82](https://github.com/openziti/desktop-edge-win/issues/82) - MTU was no longer sent to UI correctly + * [#86](https://github.com/openziti/desktop-edge-win/issues/86) - Inconsistent treatment of DNS requests - all requests will be treated as absolute going forward + * [#90](https://github.com/openziti/desktop-edge-win/issues/90) - UI will not reconnect to service if started before service + +# Release 0.0.18 + +* What's New + + * [#70](https://github.com/openziti/desktop-edge-win/issues/70) - Version added to api to report when model changes occur + +* Bug fixes + + * [#69](https://github.com/openziti/desktop-edge-win/issues/69) - reference counting for identities with access to the same service + +# Release 0.0.17 + +* What's New + + * [#70](https://github.com/openziti/desktop-edge-win/issues/70) - added api ApiVersion to TunnelStatusEvent + * [#71](https://github.com/openziti/desktop-edge-win/issues/71) - add .log to rolled over log files + +* Bug fixes + + * [#59](https://github.com/openziti/desktop-edge-win/issues/59) - too many services blocked service from accepting connections from the UI + * [#61](https://github.com/openziti/desktop-edge-win/issues/61) - identity shutdown needs to be on the uv loop (issue with forgetting identities) + * [#63](https://github.com/openziti/desktop-edge-win/issues/63) - when service restarts and UI reconnects clear identities and let the service repopulate the UI + * [#67](https://github.com/openziti/desktop-edge-win/issues/67) - set the MTU based on the value reported from the interface + +# Release 0.0.16 + +- tracking lost + +# Release 0.0.15 + +* What's New + +* Bug fixes + * [#51](https://github.com/openziti/desktop-edge-win/issues/51) - cziti log would never roll over. + now the cziti log rolls daily with a maximum of seven (7) log files + +# All versions prior to 0.0.15 + +Changelog tracking began with 0.0.15 - all previous changes were not tracked. If interested please +review the commit history. diff --git a/service/build.bat b/service/build.bat index 707a992b..83db8408 100644 --- a/service/build.bat +++ b/service/build.bat @@ -1,4 +1,5 @@ @echo off + set CURDIR=%CD% set SVC_ROOT_DIR=%~dp0 set ZITI_TUNNEL_WIN_ROOT=%SVC_ROOT_DIR%..\ @@ -13,14 +14,18 @@ IF "%1"=="quick" ( GOTO QUICK ) -echo fetching ziti-ci -call %SVC_ROOT_DIR%/../get-ziti-ci.bat -echo ziti-ci has been retrieved. running: ziti-ci version -ziti-ci version +echo fetching ziti-ci 2>&1 +call %SVC_ROOT_DIR%/../get-ziti-ci.bat 2>&1 +echo ziti-ci has been retrieved. running: ziti-ci version 2>&1 +ziti-ci version 2>&1 +echo "" -echo generating version info - this will get pushed from publish.bat in CI _if_ publish.bat started build.bat +echo generating version info - this will get pushed from publish.bat in CI _if_ publish.bat started build.bat 2>&1 ziti-ci generate-build-info --noAddNoCommit --useVersion=false %SVC_ROOT_DIR%/ziti-tunnel/version.go main --verbose 2>&1 -echo version info generated + +echo calling powershell script to update versions in UI and Installer 2>&1 +powershell -file %ZITI_TUNNEL_WIN_ROOT%update-versions.ps1 2>&1 +echo version info generated 2>&1 goto QUICK :CLEAN @@ -72,7 +77,7 @@ if exist %TUNNELER_SDK_DIR% ( echo changing to %TUNNELER_SDK_DIR% cd %TUNNELER_SDK_DIR% - + echo current directory is %CD% - should be %TUNNELER_SDK_DIR% echo. echo git clone %REPO_URL% %TUNNELER_SDK_DIR% --recurse-submodules diff --git a/service/cziti/ctun.go b/service/cziti/ctun.go index 5b5bb3ff..b47ff40e 100644 --- a/service/cziti/ctun.go +++ b/service/cziti/ctun.go @@ -50,7 +50,6 @@ extern void ZLOG(int level, char* msg); */ import "C" import ( - "errors" "golang.zx2c4.com/wireguard/tun" "io" "net" @@ -78,15 +77,16 @@ type tunnel struct { tunCtx C.tunneler_context } -var devMap = make(map[string]*tunnel) +//var devMap = make(map[string]*tunnel) +var theTun *tunnel -func HookupTun(dev tun.Device, dns []net.IP) (Tunnel, error) { +func HookupTun(dev tun.Device, dns []net.IP) error { log.Debug("in HookupTun ") defer log.Debug("exiting HookupTun") name, err := dev.Name() if err != nil { log.Error(err) - return nil, err + return err } drv := makeDriver(name) @@ -98,7 +98,8 @@ func HookupTun(dev tun.Device, dns []net.IP) (Tunnel, error) { writeQ: make(chan []byte, 64), readQ: make(chan []byte, 64), } - devMap[name] = t + //devMap[name] = t + theTun = t opts := (*C.tunneler_sdk_options)(C.calloc(1, C.sizeof_tunneler_sdk_options)) opts.netif_driver = drv @@ -115,7 +116,7 @@ func HookupTun(dev tun.Device, dns []net.IP) (Tunnel, error) { log.Infof("DNS server - waiting for startup") <-ready log.Infof("DNS server - ready") - return t, nil + return nil } func makeDriver(name string) C.netif_driver { @@ -130,15 +131,14 @@ func makeDriver(name string) C.netif_driver { //export netifWrite func netifWrite(h C.netif_handle, buf unsafe.Pointer, length C.size_t) C.ssize_t { - t, found := devMap[C.GoString(h.id)] + /*t, found := devMap[C.GoString(h.id)] if !found { - panic("should not be here") - return -1 - } + log.Panicf("An unexpected and unrecoverable error has occurred while calling netifWrite") + }*/ b := C.GoBytes(buf, C.int(length)) - t.writeQ <- b + theTun.writeQ <- b return C.ssize_t(len(b)) } @@ -151,29 +151,29 @@ func netifClose(h C.netif_handle) C.int { //export netifSetup func netifSetup(h C.netif_handle, l *C.uv_loop_t, packetCb C.packet_cb, ctx unsafe.Pointer) C.int { - t, found := devMap[C.GoString(h.id)] + /*t, found := devMap[C.GoString(h.id)] if !found { log.Error("should not be here") return -1 - } + }*/ - t.read = (*C.uv_async_t)(C.calloc(1, C.sizeof_uv_async_t)) - C.uv_async_init(l, t.read, C.uv_async_cb(C.readAsync)) - t.read.data = unsafe.Pointer(h) + theTun.read = (*C.uv_async_t)(C.calloc(1, C.sizeof_uv_async_t)) + C.uv_async_init(l, theTun.read, C.uv_async_cb(C.readAsync)) + theTun.read.data = unsafe.Pointer(h) log.Debugf("in netifSetup netif[%s] handle[%p] before", C.GoString(h.id), h) - t.idleR = (*C.uv_prepare_t)(C.calloc(1, C.sizeof_uv_prepare_t)) - C.uv_prepare_init(l, t.idleR) - t.idleR.data = unsafe.Pointer(h) - C.uv_prepare_start(t.idleR, C.uv_prepare_cb(C.readIdle)) + theTun.idleR = (*C.uv_prepare_t)(C.calloc(1, C.sizeof_uv_prepare_t)) + C.uv_prepare_init(l, theTun.idleR) + theTun.idleR.data = unsafe.Pointer(h) + C.uv_prepare_start(theTun.idleR, C.uv_prepare_cb(C.readIdle)) log.Debugf("in netifSetup netif[%s] handle[%p] after", C.GoString(h.id), h) - t.onPacket = packetCb - t.onPacketCtx = ctx - t.loop = l + theTun.onPacket = packetCb + theTun.onPacketCtx = ctx + theTun.loop = l - go t.runWriteLoop() - go t.runReadLoop() + go theTun.runWriteLoop() + go theTun.runReadLoop() return C.int(0) } @@ -181,7 +181,7 @@ func netifSetup(h C.netif_handle, l *C.uv_loop_t, packetCb C.packet_cb, ctx unsa func (t *tunnel) runReadLoop() { mtu, err := t.dev.MTU() if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "getting the MTU", err) } log.Debugf("starting tun read loop mtu=%d", mtu) defer log.Debug("tun read loop is done") @@ -193,7 +193,7 @@ func (t *tunnel) runReadLoop() { //that's fine... return } - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "reading from the tun device", err) } if len(t.readQ) == cap(t.readQ) { @@ -209,21 +209,20 @@ func (t *tunnel) runReadLoop() { //export readIdle func readIdle(idler *C.uv_prepare_t) { - dev := (*C.netif_handle_t)(idler.data) + /*dev := (*C.netif_handle_t)(idler.data) id := C.GoString(dev.id) t, found := devMap[id] if !found { - log.Debug("should not be here id = [%s]", id) - panic(errors.New("where is my tunnel?")) - } + log.Panicf("An unexpected and unrecoverable error has occurred while looking for tun in devMap") + }*/ - np := len(t.readQ) + np := len(theTun.readQ) for i := np; i > 0; i-- { - b := <-t.readQ + b := <-theTun.readQ buf := C.CBytes(b) - C.call_on_packet(buf, C.ssize_t(len(b)), t.onPacket, t.onPacketCtx) + C.call_on_packet(buf, C.ssize_t(len(b)), theTun.onPacket, theTun.onPacketCtx) C.free(buf) } @@ -246,7 +245,7 @@ func (t *tunnel) runWriteLoop() { n, err := t.dev.Write(p, 0) if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "writing to tun device", err) } if n < len(p) { @@ -255,11 +254,21 @@ func (t *tunnel) runWriteLoop() { } } } - +/* func (t *tunnel) AddIntercept(svcId string, service string, host string, port int, ctx unsafe.Pointer) { log.Debugf("about to add intercept for: %s, %s, %d", service, host, port) res := C.ziti_tunneler_intercept_v1(t.tunCtx, ctx, C.CString(svcId), C.CString(service), C.CString(host), C.int(port)) log.Debugf("intercept added: %v", res) +}*/ + +func AddIntercept(svcId string, service string, host string, port int, ctx unsafe.Pointer) { + /*for _, t := range devMap { + log.Debug("adding intercept for: %s, %s, %d", service, host, port) + t.AddIntercept(svcId, service, host, int(port), unsafe.Pointer(ctx)) + } + */ + log.Debugf("about to add intercept for: %s[] at %s:%d", service, svcId, host, port) + _ = C.ziti_tunneler_intercept_v1(theTun.tunCtx, ctx, C.CString(svcId), C.CString(service), C.CString(host), C.int(port)) } type RemoveWG struct { @@ -280,20 +289,13 @@ func remove_intercepts(async *C.uv_async_t) { //c := (*C.char)(async.data) rwg := (*RemoveWG)(async.data) - for _, t := range devMap { + /*for _, t := range devMap { //C.ZLOG(C.INFO, C.CString("bbb on uv thread - inside remove_intercepts")) C.ziti_tunneler_stop_intercepting(t.tunCtx, C.CString(rwg.SvcId)) - } + }*/ + C.ziti_tunneler_stop_intercepting(theTun.tunCtx, C.CString(rwg.SvcId)) //C.ZLOG(C.INFO, C.CString("ccc on uv thread - inside remove_intercepts")) C.uv_close((*C.uv_handle_t)(unsafe.Pointer(async)), C.uv_close_cb(C.free_async)) C.ZLOG(C.INFO, C.CString("on uv thread - completed remove_intercepts")) rwg.Wg.Done() } - -func AddIntercept(svcId string, service string, host string, port uint16, ctx *CZitiCtx) { - for _, t := range devMap { - log.Debug("adding intercept for: %s, %s, %d", service, host, port) - res := C.ziti_tunneler_intercept_v1(t.tunCtx, unsafe.Pointer(ctx.zctx), C.CString(svcId), C.CString(service), C.CString(host), C.int(port)) - log.Debugf("intercept added: %v", res) - } -} diff --git a/service/cziti/cziti-cli/main.go b/service/cziti/cziti-cli/main.go deleted file mode 100644 index 8191b9c3..00000000 --- a/service/cziti/cziti-cli/main.go +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright NetFoundry, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package main - -import "C" -import ( - "bufio" - "errors" - "fmt" - "os" - "strconv" - "strings" - "github.com/openziti/desktop-edge-win/service/cziti" -) - -func main() { - cziti.Start() - - fmt.Println("welcome to cziti-cli testing") - fmt.Println("----------------------------") - fmt.Println() - - reader := bufio.NewReader(os.Stdin) - for { - fmt.Print("-> ") - text, _ := reader.ReadString('\n') - - text = strings.TrimSpace(text) - cmd := strings.Split(text, " ") - - if f, found := commands[cmd[0]]; found { - err := f(cmd[1:]) - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "error: %v", err) - } - fmt.Println() - } else { - fmt.Printf("command `%s' is not found\n", cmd[0]) - } - } -} - -var commands = make(map[string]func([]string) error) - -func init() { - commands["quit"] = quit - commands["help"] = help - commands["list"] = list - commands["load"] = load - commands["show-services"] = showServices -} - -func showServices(args []string) error { - if len(args) == 0 { - return errors.New("select context") - } - - idx, err := strconv.Atoi(args[0]) - if err != nil { - return err - } - - if idx >= len(contexts) { - return errors.New("invalid reference") - } - - ctx := contexts[idx] - - fmt.Printf("services available to %s@%s\n", ctx.Name(), ctx.Controller()) - ctx.Services.Range(func(key interface{}, value interface{}) bool { - fmt.Printf("\t%v=%v\n", key, value) - return true - }) - return nil -} - -func quit(_ []string) error { - cziti.Stop() - os.Exit(0) - return nil -} - -func help(_ []string) error { - fmt.Println("available commands:") - for k, _ := range commands { - fmt.Println("\t", k) - } - return nil -} - -var contexts []*cziti.CZitiCtx - -func load(args []string) error { - if len(args) == 0 { - return fmt.Errorf("path to configfile required") - } - - ctx := cziti.LoadZiti(args[0]) - fmt.Printf("successfully loaded %s@%s\n", ctx.Name(), ctx.Controller()) - contexts = append(contexts, ctx) - - return nil -} - -func list(args []string) error { - fmt.Println("loaded ziti identities:") - for i, c := range contexts { - fmt.Printf("\t%d:\t%s@%s\n", i, c.Name(), c.Controller()) - } - return nil -} diff --git a/service/cziti/dns-proxy.go b/service/cziti/dns-proxy.go index c081e2e7..d0ae91aa 100644 --- a/service/cziti/dns-proxy.go +++ b/service/cziti/dns-proxy.go @@ -146,7 +146,7 @@ func runListener(ip net.IP, port int, reqch chan dnsreq) { server, err := net.ListenUDP(network, laddr) if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "udp listening on network", err) } for { @@ -159,7 +159,7 @@ func runListener(ip net.IP, port int, reqch chan dnsreq) { break } else { _ = server.Close() - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "reading a udp message", err) } } @@ -259,7 +259,6 @@ func runDNSproxy(dnsServers []string) { b, _ := pr.req.Pack() for _, proxy := range dnsUpstreams { if _, err := proxy.Write(b); err != nil { - //TODO: if this happens -does this mean the next dns server is not available? _ = proxy.Close() //first thing - close the proxy connection @@ -299,7 +298,7 @@ func runDNSproxy(dnsServers []string) { now := time.Now() for k, r := range reqs { if now.After(r.exp) { - log.Warn("a DNS request has expired - enable trace logging and reproduce this issue for more information") + log.Debugf("a DNS request has expired - enable trace logging and reproduce this issue for more information") log.Tracef(" expired DNS req: %s %s", dns.Type(r.req.Question[0].Qtype), r.req.Question[0].Name) delete(reqs, k) diff --git a/service/cziti/dns.go b/service/cziti/dns.go index 43c4a030..fad7c906 100644 --- a/service/cziti/dns.go +++ b/service/cziti/dns.go @@ -21,8 +21,7 @@ import "C" import ( "encoding/binary" "fmt" - "github.com/openziti/desktop-edge-win/service/ziti-tunnel/constants" - + "github.com/openziti/desktop-edge-win/service/ziti-tunnel/api" "net" "strings" "sync" @@ -50,6 +49,16 @@ type dnsImpl struct { hostnameMap map[string]ctxIp // ipv4 -> dnsName //ipMap map[uint32]string + tun api.DesktopEdgeIface +} + +type intercept struct { + host string + port uint16 + isIp bool +} +func (i intercept) String() string { + return fmt.Sprintf("%s:%d", i.host, i.port) } type ctxIp struct { @@ -63,6 +72,7 @@ type ctxService struct { name string serviceId string count int + icept intercept } func normalizeDnsName(dnsName string) string { @@ -78,17 +88,24 @@ func normalizeDnsName(dnsName string) string { // RegisterService will return the next ip address in the configured range. If the ip address is not // assigned to a hostname an error will also be returned indicating why. func (dns *dnsImpl) RegisterService(svcId string, dnsNameToReg string, port uint16, ctx *CZitiCtx, svcName string) (net.IP, error) { - log.Infof("adding DNS entry for service name %s@%s:%d", svcName, dnsNameToReg, port) - DnsInit(constants.Ipv4ip, constants.Ipv4DefaultMask) - dnsName := normalizeDnsName(dnsNameToReg) - key := fmt.Sprint(dnsName, ':', port) + //check to see if host is an ip address - if so we want to intercept the ip. otherwise treat host as a host + //name and register it in dns, obtain an ip and all that... + ip := net.ParseIP(dnsNameToReg) - var ip net.IP + icept := intercept{isIp: false, port: port} + if ip == nil { + icept.host = normalizeDnsName(dnsNameToReg) + } else { + icept.host = ip.String() + icept.isIp = true + } + key := icept.String() + log.Infof("adding DNS for %s. service name %s@%s", dnsNameToReg, svcName, key) currentNetwork := C.GoString(ctx.Options.controller) // check to see if the hostname is mapped... - if foundIp, found := dns.hostnameMap[dnsName]; found { + if foundIp, found := dns.hostnameMap[icept.host]; found { ip = foundIp.ip // now check to see if the host *and* port are mapped... if foundContext, found := dns.serviceMap[key]; found { @@ -103,36 +120,44 @@ func (dns *dnsImpl) RegisterService(svcId string, dnsNameToReg string, port uint // while the host *AND* port are not used - the hostname is. // need to increment the refcounter of how many service use this hostname foundContext.count ++ - log.Debugf("DNS mapping for %s used by another service. total services using %s = %d", dnsNameToReg, dnsNameToReg, foundContext.count) + log.Debugf("DNS mapping used by another service. total services using %s = %d", dnsNameToReg, foundContext.count) } else { // good - means the service can be mapped - dns.serviceMap[key] = ctxService{ - ctx: ctx, - name: svcName, - serviceId: svcId, - count: 1, - } } } else { // if not used at all - map it - nextAddr := dns.cidr | atomic.AddUint32(&dns.ipCount, 1) - ip = make(net.IP, 4) - binary.BigEndian.PutUint32(ip, nextAddr) + if icept.isIp { + err := dns.tun.AddRoute( + net.IPNet{IP: ip, Mask: net.IPMask{255, 255, 255, 255}}, + net.IP{0,0,0,0}, + 1) + if err != nil { + log.Errorf("Unexpected error adding a route to %s: %v", icept.host, err) + } else { + log.Infof("adding route for ip:%s", icept.host) + } + } else { + nextAddr := dns.cidr | atomic.AddUint32(&dns.ipCount, 1) + ip = make(net.IP, 4) + binary.BigEndian.PutUint32(ip, nextAddr) - log.Infof("mapping hostname %s to ip %s", dnsNameToReg, ip.String()) - dns.hostnameMap[dnsName] = ctxIp { - ip: ip, - ctx: ctx, - network: currentNetwork, - } - dns.serviceMap[key] = ctxService{ - ctx: ctx, - name: svcName, - serviceId: svcId, - count: 1, + log.Infof("mapping hostname %s to ip %s", dnsNameToReg, ip.String()) + dns.hostnameMap[icept.host] = ctxIp { + ip: ip, + ctx: ctx, + network: currentNetwork, + } } } + dns.serviceMap[key] = ctxService{ + ctx: ctx, + name: svcName, + serviceId: svcId, + count: 1, + icept: icept, + } + return ip, nil } @@ -141,15 +166,23 @@ func (dns *dnsImpl) Resolve(toResolve string) net.IP { return dns.hostnameMap[dnsName].ip } -func (dns *dnsImpl) DeregisterService(ctx *CZitiCtx, name string) { - log.Debugf("DEREG SERVICE: before for loop") - for k, sc := range dns.serviceMap { - log.Debugf("DEREG SERVICE: iterating sc.ctx=ctx %p=%p, sc.name=name %s=%s", sc.ctx, ctx, sc.name, name) +func (dns *dnsImpl) UnregisterService(ctx *CZitiCtx, name string) { + log.Debugf("UnregisterService named %s called for controller %s and identity: %s.", name, ctx.Controller(), ctx.Name()) + for key, sc := range dns.serviceMap { if sc.ctx == ctx && sc.name == name { sc.count -- if sc.count < 1 { - log.Infof("removing service named %s from DNS mapping known as %s", name, k) - delete(dns.serviceMap, k) + icept := sc.icept + log.Infof("removing service named %s from DNS mapping known as %s", name, icept) + if icept.isIp { + err := dns.tun.RemoveRoute(net.IPNet{IP: net.ParseIP(icept.host)}, net.IP{0, 0, 0, 0}) + if err != nil { + log.Warnf("Unexpected error removing route for %s", icept.host) + } + } else { + delete(dns.hostnameMap, icept.host) + } + delete(dns.serviceMap, key) } else { // another service is using the mapping - can't remove it yet so decrement log.Debugf("cannot remove dns mapping for %s yet - %d other services still use this hostname", name, sc.count) @@ -159,7 +192,7 @@ func (dns *dnsImpl) DeregisterService(ctx *CZitiCtx, name string) { log.Debugf("service context %p does not match event context address %p", sc.ctx, ctx) } } - log.Warnf("DEREG SERVICE: for loop completed. Match was not found for context %p and name %s", ctx, name) + log.Warnf("UnregisterService completed. Match was not found for context %p and name %s", ctx, name) } func (this *dnsImpl) GetService(ip net.IP, port uint16) (*CZitiCtx, string, error) { @@ -179,7 +212,7 @@ func (this *dnsImpl) GetService(ip net.IP, port uint16) (*CZitiCtx, string, erro */ } -func DnsInit(ip string, maskBits int) { +func DnsInit(tun api.DesktopEdgeIface, ip string, maskBits int) { initOnce.Do(func() { DNS.serviceMap = make(map[string]ctxService) //DNS.ipMap = make(map[uint32]string) @@ -188,5 +221,6 @@ func DnsInit(ip string, maskBits int) { mask := net.CIDRMask(maskBits, 32) DNS.cidr = binary.BigEndian.Uint32(i) & binary.BigEndian.Uint32(mask) DNS.ipCount = 2 + DNS.tun = tun }) } diff --git a/service/cziti/sdk.go b/service/cziti/sdk.go index 28b33bf5..a591b2bb 100644 --- a/service/cziti/sdk.go +++ b/service/cziti/sdk.go @@ -170,7 +170,7 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, t found, ok := ctx.Services.Load(svcId) if ok { fs := found.(Service) - DNS.DeregisterService(ctx, name) + DNS.UnregisterService(ctx, name) ctx.Services.Delete(svcId) ServiceChanges <- ServiceChange{ Operation: REMOVED, @@ -178,7 +178,7 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, t ZitiContext: ctx, } } else { - log.Warnf("could not remove service? service not found with id: %s, name: %s in context %d", service.id, service.name, &ctx) + log.Warnf("could not remove service? service not found with id: %s, name: %s in context %d", svcId, name, &ctx) } } else if status == C.ZITI_OK { //first thing's first - determine if the service is already in this runtime @@ -187,7 +187,7 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, t found, ok := ctx.Services.Load(svcId) if ok && found != nil { log.Infof("service with id: %s, name: %s exists. updating service.", service.id, service.name) - DNS.DeregisterService(ctx, name) + DNS.UnregisterService(ctx, name) ctx.Services.Delete(svcId) } else { log.Debugf("service not found with id: %s, name: %s in context %d", svcId, name, &ctx) @@ -199,10 +199,11 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, t // int ziti_service_get_config(ziti_service *service, const char *cfg_type, void *cfg, int (*parser)(void *, const char *, size_t)) r := C.ziti_service_get_config(service, C.CString("ziti-tunneler-server.v1"), unsafe.Pointer(&v1Config), (*[0]byte)(C.parse_ziti_server_cfg_v1)) if (r == 0) { - for _, t := range devMap { + /*for _, t := range devMap { log.Debugf("setting up hosted service for service %s on %v:%v", service.name, v1Config.hostname, v1Config.port) C.ziti_tunneler_host_v1(C.tunneler_context(t.tunCtx), unsafe.Pointer(ctx.zctx), service.name, v1Config.protocol, v1Config.hostname, v1Config.port) - } + }*/ + C.ziti_tunneler_host_v1(C.tunneler_context(theTun.tunCtx), unsafe.Pointer(ctx.zctx), service.name, v1Config.protocol, v1Config.hostname, v1Config.port) C.free_ziti_server_cfg_v1(&v1Config) } else { log.Infof("service is bindable but doesn't have config? %s. flags: %v.", name, service.perm_flags) @@ -229,9 +230,10 @@ func serviceCB(ziti_ctx C.ziti_context, service *C.ziti_service, status C.int, t ownsIntercept = false } else { log.Infof("service intercept beginning for service: %s@%s:%d on ip %s", name, host, port, ip.String()) - for _, t := range devMap { + /*for _, t := range devMap { t.AddIntercept(svcId, name, ip.String(), port, unsafe.Pointer(ctx.zctx)) - } + }*/ + AddIntercept(svcId, name, ip.String(), port, unsafe.Pointer(ctx.zctx)) } added := Service{ Name: name, diff --git a/service/cziti/windns.go b/service/cziti/windns.go index 6c15284c..78af9308 100644 --- a/service/cziti/windns.go +++ b/service/cziti/windns.go @@ -55,7 +55,7 @@ func GetConnectionSpecificDomains() []string { err := cmd.Run() if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while running the command: %s %v", script, err) } var names []string @@ -85,7 +85,7 @@ func GetUpstreamDNS() []string { err := cmd.Run() if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while running the command: %s %v", script, err) } var names []string diff --git a/service/publish.bat b/service/publish.bat index e5e68552..a8323834 100644 --- a/service/publish.bat +++ b/service/publish.bat @@ -1,96 +1,97 @@ @echo off + set CURDIR=%CD% set SVC_ROOT_DIR=%~dp0 set /p BUILD_VERSION=<%SVC_ROOT_DIR%..\version IF "%BUILD_VERSION%"=="" GOTO BUILD_VERSION_ERROR -@echo mkdir %USERPROFILE%\.ssh and add github.com to known_hosts... 2>&1 +echo mkdir %USERPROFILE%\.ssh and add github.com to known_hosts... 2>&1 mkdir %USERPROFILE%\.ssh 2>&1 -@echo adding github key: ssh-keyscan -t rsa github.com 2>&1 +echo adding github key: ssh-keyscan -t rsa github.com 2>&1 ssh-keyscan -t rsa github.com >> %USERPROFILE%\.ssh\known_hosts 2>&1 -@echo looking for key using: ssh-keygen -F github.com - expect to find it now! 2>&1 +echo looking for key using: ssh-keygen -F github.com - expect to find it now! 2>&1 ssh-keygen -F github.com 2>&1 +echo converting shallow clone so travis can co: %GIT_BRANCH% +git remote set-branches origin %GIT_BRANCH% 2>&1 +git fetch --depth 1 origin %GIT_BRANCH% 2>&1 +git checkout %GIT_BRANCH% 2>&1 +CALL :FAIL %ERRORLEVEL% "checkout failed" +echo git checkout %GIT_BRANCH% complete: %ERRORLEVEL% + call %SVC_ROOT_DIR%\build.bat SET ACTUAL_ERR=%ERRORLEVEL% if %ACTUAL_ERR% NEQ 0 ( @echo. - @echo call to build.bat failed with %ACTUAL_ERR% + echo call to build.bat failed with %ACTUAL_ERR% @echo. exit /b 1 ) else ( @echo. - @echo result of ninja build: %ACTUAL_ERR% + echo result of ninja build: %ACTUAL_ERR% ) IF "%GIT_BRANCH%"=="master" GOTO RELEASE -@echo Publishing to snapshot repo +echo Publishing to snapshot repo ziti-ci publish artifactory --groupId=ziti-tunnel-win.amd64.windows --artifactId=ziti-tunnel-win --version=%BUILD_VERSION%-SNAPSHOT --target=service/ziti-tunnel-win.zip 2>&1 REM ziti-ci publish artifactory --groupId=ziti-tunnel-win.amd64.windows --artifactId=ziti-tunnel-win --version=%BUILD_VERSION%-SNAPSHOT --target=service/ziti-tunnel-win.zip --classifier=%GIT_BRANCH% 2>&1 GOTO END :RELEASE -@echo Publishing release +echo Publishing release ziti-ci publish artifactory --groupId=ziti-tunnel-win.amd64.windows --artifactId=ziti-tunnel-win --version=%BUILD_VERSION% --target=service/ziti-tunnel-win.zip 2>&1 GOTO END :BUILD_VERSION_ERROR -@echo The build version environment variable was not set - cannot publish +echo The build version environment variable was not set - cannot publish exit /b 1 :FAIL IF %~1 NEQ 0 ( - @echo ================================================================ + echo ================================================================ @echo. - @echo FAILURE: - @echo %~2 + echo FAILURE: + echo %~2 @echo. - @echo ================================================================ + echo ================================================================ exit /b %~1 ) exit /b 0 :END -@echo publishing complete - committing version.go as ci -@echo changing back to: %CURDIR% +echo publishing complete - committing version.go as ci +echo changing back to: %CURDIR% cd %CURDIR% -@echo current dir: %CD% +echo current dir: %CD% -@echo configuring git - relies on build.bat successfully grabbing ziti-ci and build.bat updating service/ziti-tunnel/version.go +echo configuring git - relies on build.bat successfully grabbing ziti-ci and build.bat updating service/ziti-tunnel/version.go ziti-ci configure-git 2>&1 -@echo converting shallow clone so travis can co: %GIT_BRANCH% -git remote set-branches origin %GIT_BRANCH% 2>&1 -git fetch --depth 1 origin %GIT_BRANCH% 2>&1 -git checkout %GIT_BRANCH% 2>&1 -CALL :FAIL %ERRORLEVEL% "checkout failed" -@echo git checkout %GIT_BRANCH% complete: %ERRORLEVEL% - -@echo issuing status -@echo ======================================================== +echo issuing status +echo ======================================================== git status 2>&1 -git add service/ziti-tunnel/version.go 2>&1 +git add service/ziti-tunnel/version.go DesktopEdge/Properties/AssemblyInfo.cs Installer/ZitiDesktopEdge.aip 2>&1 CALL :FAIL %ERRORLEVEL% "git add failed" -@echo git add service/ziti-tunnel/version.go complete: %ERRORLEVEL% +echo git add service/ziti-tunnel/version.go DesktopEdge/Properties/AssemblyInfo.cs Installer/ZitiDesktopEdge.aip complete: %ERRORLEVEL% -@echo issuing commit -git commit -m "[ci skip] committing updated version information" 2>&1 +echo issuing commit +git commit -m "[ci skip] - [***NO_CI***] [skip ci] committing updated version information" 2>&1 CALL :FAIL %ERRORLEVEL% "git commit failed" -@echo git commit -m "[ci skip] committing updated version information" complete: %ERRORLEVEL% -@echo ======================================================== -@echo issuing git push -@echo ======================================================== -@echo setting git config remote.url git@github.com:openziti/desktop-edge-win.git +echo git commit -m "[ci skip] - [***NO_CI***] [skip ci] committing updated version information"" complete: %ERRORLEVEL% +echo ======================================================== +echo issuing git push +echo ======================================================== +echo setting git config remote.url git@github.com:openziti/desktop-edge-win.git git config remote.url git@github.com:openziti/desktop-edge-win.git 2>&1 git config --list 2>&1 dir github_deploy_key git push --verbose 2>&1 CALL :FAIL %ERRORLEVEL% "git push failed" -@echo git push complete: %ERRORLEVEL% -@echo publish script has completed +echo git push complete: %ERRORLEVEL% +echo publish script has completed diff --git a/service/set-env.bat b/service/set-env.bat new file mode 100644 index 00000000..db03d590 --- /dev/null +++ b/service/set-env.bat @@ -0,0 +1,4 @@ +set SVC_ROOT_DIR=%~dp0 +SET TUNNELER_SDK_DIR=%SVC_ROOT_DIR%deps\ziti-tunneler-sdk-c\ +SET CGO_CFLAGS=-DNOGDI -I %TUNNELER_SDK_DIR%install\include +SET CGO_LDFLAGS=-L %TUNNELER_SDK_DIR%install\lib \ No newline at end of file diff --git a/service/ziti-tunnel/api/api.go b/service/ziti-tunnel/api/api.go new file mode 100644 index 00000000..2332ded7 --- /dev/null +++ b/service/ziti-tunnel/api/api.go @@ -0,0 +1,29 @@ +package api + +import "net" + +type DesktopEdgeIface interface { + AddRoute(destination net.IPNet, nextHop net.IP, metric uint32) error + RemoveRoute(destination net.IPNet, nextHop net.IP) error + + InterceptDNS() + ReleaseDNS() + + InterceptIP() + ReleaseIP() + + Close() +} + +type DesktopEdgeManager interface { + AddIdentity() + RemoveIdentity() + Status() + TunnelState() + IdentityToggle() + SetLogLevel() + Debug() + SaveState() + CreateTun() + FindIdentity() +} \ No newline at end of file diff --git a/service/ziti-tunnel/main.go b/service/ziti-tunnel/main.go index ac96141f..9a4b0fb9 100644 --- a/service/ziti-tunnel/main.go +++ b/service/ziti-tunnel/main.go @@ -1,3 +1,5 @@ +// +build windows + /* * Copyright NetFoundry, Inc. * @@ -14,8 +16,6 @@ * limitations under the License. * */ - -// +build windows package main import ( diff --git a/service/ziti-tunnel/service/ipc.go b/service/ziti-tunnel/service/ipc.go index 037c01bb..41a9ae56 100644 --- a/service/ziti-tunnel/service/ipc.go +++ b/service/ziti-tunnel/service/ipc.go @@ -44,6 +44,7 @@ import ( "strings" "sync" "time" + "unsafe" ) type Pipes struct { @@ -279,7 +280,7 @@ func setTunInfo(s *dto.TunnelStatus, ipv4 string, ipv4mask int) { func ipv4MaskString(m []byte) string { if len(m) != 4 { - panic("ipv4Mask: len must be 4 bytes") + log.Panicf("An unexpected and unrecoverable error has occurred. ipv4Mask: len must be 4 bytes") } return fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3]) @@ -314,7 +315,7 @@ func serveIpc(conn net.Conn) { events.broadcast <- dto.TunnelStatusEvent{ StatusEvent: dto.StatusEvent{Op: "status"}, Status: rts.ToStatus(), - ApiVersion: API_VERSION, + ApiVersion: API_VERSION, } done := make(chan struct{}, 8) @@ -523,7 +524,7 @@ func serveEvents(conn net.Conn) { err := o.Encode( dto.TunnelStatusEvent{ StatusEvent: dto.StatusEvent{Op: "status"}, Status: rts.ToStatus(), - ApiVersion: API_VERSION, + ApiVersion: API_VERSION, }) if err != nil { @@ -686,7 +687,7 @@ func newIdentity(newId dto.AddIdentity, out *json.Encoder) { err = enrolled.Close() if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "enrolling an identity", err) } newPath := newId.Id.Path() @@ -733,7 +734,7 @@ func connectIdentity(id *dto.Identity) { } else { log.Debugf("id [%s] is already connected - not reconnecting", id.Name) for _, s := range id.Services { - cziti.AddIntercept(s.Id, s.Name, s.InterceptHost, s.InterceptPort, id.ZitiContext) + cziti.AddIntercept(s.Id, s.Name, s.InterceptHost, int(s.InterceptPort), unsafe.Pointer(id.ZitiContext)) } id.Connected = true } @@ -772,7 +773,7 @@ func disconnectIdentity(id *dto.Identity) error { } cziti.RemoveIntercept(rwg) wg.Wait() - cziti.DNS.DeregisterService(id.ZitiContext, s.Name) + cziti.DNS.UnregisterService(id.ZitiContext, s.Name) } id.Connected = false } else { @@ -795,10 +796,10 @@ func removeIdentity(out *json.Encoder, fingerprint string) { return } - rts.RemoveByIdentity(*id) + rts.RemoveByFingerprint(fingerprint) //remove the file from the filesystem - first verify it's the proper file - log.Debug("removing identity file for fingerprint %s at %s", id.FingerPrint, id.Path()) + log.Debugf("removing identity file for fingerprint %s at %s", id.FingerPrint, id.Path()) err = os.Remove(id.Path()) if err != nil { log.Warn("could not remove file: %s", config.Path()+id.FingerPrint+".json") diff --git a/service/ziti-tunnel/service/state.go b/service/ziti-tunnel/service/state.go index d7a3aa90..de340a82 100644 --- a/service/ziti-tunnel/service/state.go +++ b/service/ziti-tunnel/service/state.go @@ -59,21 +59,13 @@ func (t *RuntimeState) Find(fingerprint string) (int, *dto.Identity) { return len(t.state.Identities), nil } -func (t *RuntimeState) RemoveByIdentity(id dto.Identity) { - t.RemoveByFingerprint(id.FingerPrint) -} - -func (t *RuntimeState) FindByIdentity(id dto.Identity) (int, *dto.Identity) { - return t.Find(id.FingerPrint) -} - func (t *RuntimeState) SaveState() { // overwrite file if it exists _ = os.MkdirAll(config.Path(), 0644) cfg, err := os.OpenFile(config.File(), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "opening the config file", err) } w := bufio.NewWriter(bufio.NewWriter(cfg)) enc := json.NewEncoder(w) @@ -83,7 +75,7 @@ func (t *RuntimeState) SaveState() { err = cfg.Close() if err != nil { - panic(err) + log.Panicf("An unexpected and unrecoverable error has occurred while %s: %v", "closing the config file", err) } log.Debug("state saved") } @@ -195,11 +187,11 @@ func (t *RuntimeState) CreateTun(ipv4 string, ipv4mask int) error { } log.Info("routing applied") - cziti.DnsInit(ipv4, ipv4mask) + cziti.DnsInit(&rts, ipv4, ipv4mask) cziti.Start() - _, err = cziti.HookupTun(tunDevice, dns) + err = cziti.HookupTun(tunDevice, dns) if err != nil { - panic(err) + log.Panicf("An unrecoverable error has occurred! %v", err) } return nil } @@ -242,18 +234,6 @@ func noZiti() bool { return v } -func (t *RuntimeState) Close() { - if t.tun != nil { - tu := *t.tun - err := tu.Close() - if err != nil { - log.Fatalf("problem closing tunnel!") - } - } else { - log.Warn("unexpected situation. the TUN was null? ") - } -} - func (t *RuntimeState) LoadConfig() { log.Infof("reading config file located at: %s", config.File()) file, err := os.OpenFile(config.File(), os.O_RDONLY, 0644) @@ -309,4 +289,46 @@ func iPv6Disabled() bool { log.Infof("IPv6 has DisabledComponents set to %d. If the service fails to start please report this message", val) return false } -} \ No newline at end of file +} + +func (r *RuntimeState) AddRoute(destination net.IPNet, nextHop net.IP, metric uint32) error { + nativeTunDevice := (*r.tun).(*tun.NativeTun) + luid := winipcfg.LUID(nativeTunDevice.LUID()) + return luid.AddRoute(destination, nextHop, metric) +} + +func (r *RuntimeState) RemoveRoute(destination net.IPNet, nextHop net.IP) error { + nativeTunDevice := (*r.tun).(*tun.NativeTun) + luid := winipcfg.LUID(nativeTunDevice.LUID()) + return luid.DeleteRoute(destination, nextHop) +} + + +func (t *RuntimeState) Close() { + if t.tun != nil { + tu := *t.tun + err := tu.Close() + if err != nil { + log.Fatalf("problem closing tunnel!") + } + } else { + log.Warn("unexpected situation. the TUN was null? ") + } +} + + +func (t *RuntimeState) InterceptDNS() { + log.Panicf("implement me") +} + +func (t *RuntimeState) ReleaseDNS() { + log.Panicf("implement me") +} + +func (t *RuntimeState) InterceptIP() { + log.Panicf("implement me") +} + +func (t *RuntimeState) ReleaseIP() { + log.Panicf("implement me") +} diff --git a/service/ziti-tunnel/version.go b/service/ziti-tunnel/version.go index d25926e2..2ab159c8 100644 --- a/service/ziti-tunnel/version.go +++ b/service/ziti-tunnel/version.go @@ -20,9 +20,9 @@ package main const ( - Version = "1.2.10" - Revision = "685f5cb076f5" - Branch = "master" + Version = "1.2.11" + Revision = "62aef98d6c7f" + Branch = "release-1.2.11" BuildUser = "travis" - BuildDate = "2020-10-15 21:03:33" + BuildDate = "2020-10-21 04:32:10" ) diff --git a/update-versions.ps1 b/update-versions.ps1 new file mode 100644 index 00000000..960c205a --- /dev/null +++ b/update-versions.ps1 @@ -0,0 +1,25 @@ +echo "==================================== update-versions.ps1 begins ====================================" +echo "Obtaining version information from .\version" +$v=(Get-Content -Path .\version) +echo " version: $v" +echo "" + +rm temp.cs -ErrorAction Ignore +rm temp.aip -ErrorAction Ignore + +$assemblyInfo="./DesktopEdge/Properties/AssemblyInfo.cs" +$assemblyInfoReplaced="${assemblyInfo}.replaced" +$installer="./Installer/ZitiDesktopEdge.aip" +$installerReplaced="${installer}.replaced" + +echo "Replacing version in $assemblyInfo into $assemblyInfoReplaced" +(Get-Content -Encoding UTF8 -path $assemblyInfo -Raw) -replace 'Version\("[0-9]*.[0-9]*.[0-9]*.0', "Version(""${v}.0" | Set-Content -Encoding UTF8 -Path "$assemblyInfoReplaced" -NoNewline +rm $assemblyInfo +mv $assemblyInfoReplaced $assemblyInfo + +echo "Replacing version in $installer into $installerReplaced" +(Get-Content -Encoding UTF8 -path $installer -Raw) -replace '"ProductVersion" Value="[0-9]*\.[0-9]*\.[0-9]*"', """ProductVersion"" Value=""${v}""" | Set-Content -Path "${installer}.replaced" -Encoding UTF8 -NoNewline +rm $installer +mv $installerReplaced $installer + +echo "==================================== update-versions.ps1 complete ====================================" \ No newline at end of file diff --git a/version b/version index 963ed7cf..c1147005 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.2.10 +1.2.11