diff --git a/.github/workflows/check-go-dependencies-task.yml b/.github/workflows/check-go-dependencies-task.yml index 5b78888bb..417c525e5 100644 --- a/.github/workflows/check-go-dependencies-task.yml +++ b/.github/workflows/check-go-dependencies-task.yml @@ -72,11 +72,17 @@ jobs: with: submodules: recursive + # This is required to allow licensee/setup-licensed to install Licensed via Ruby gem. + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby # Install latest version + - name: Install licensed - uses: jonabc/setup-licensed@v1 + uses: licensee/setup-licensed@v1.3.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} - version: 3.x + version: 5.x - name: Install Go uses: actions/setup-go@v5 @@ -123,11 +129,17 @@ jobs: with: submodules: recursive + # This is required to allow licensee/setup-licensed to install Licensed via Ruby gem. + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby # Install latest version + - name: Install licensed - uses: jonabc/setup-licensed@v1 + uses: licensee/setup-licensed@v1.3.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} - version: 3.x + version: 5.x - name: Install Go uses: actions/setup-go@v5 diff --git a/.github/workflows/publish-go-tester-task.yml b/.github/workflows/publish-go-tester-task.yml index 8e72c351a..89d5c2b45 100644 --- a/.github/workflows/publish-go-tester-task.yml +++ b/.github/workflows/publish-go-tester-task.yml @@ -65,7 +65,7 @@ jobs: #use the strategy instead because we still use the native build strategy: matrix: - os: [ubuntu-20.04, windows-2019, macos-13] + os: [ubuntu-22.04, windows-2019, macos-13] arch: [-amd64] include: - os: windows-2019 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3b2a210d9..12b3781ba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,7 +32,7 @@ jobs: prerelease: ${{ steps.prerelease.outputs.IS_PRE }} strategy: matrix: - os: [ubuntu-20.04, windows-2019, macos-13] + os: [ubuntu-22.04, windows-2019, macos-13] arch: [amd64] include: - os: windows-2019 @@ -88,7 +88,7 @@ jobs: - name: Build the Agent for linux run: task go:build - if: matrix.os == 'ubuntu-20.04' + if: matrix.os == 'ubuntu-22.04' # the manifest is required by windows GUI apps, otherwise the binary will crash with: "Unable to create main window: TTM_ADDTOOL failed" (for reference https://github.com/lxn/walk/issues/28) # rsrc will produce a *.syso file that should get automatically recognized by go build command and linked into an executable. @@ -259,6 +259,11 @@ jobs: environment: production steps: + - name: Install Go + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + - name: Download artifact uses: actions/download-artifact@v4 with: @@ -385,7 +390,7 @@ jobs: # This job is responsible for generating the installers (using installbuilder) package: needs: build - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: # vars used by installbuilder @@ -395,10 +400,10 @@ jobs: strategy: fail-fast: false # if one os is failing continue nonetheless matrix: # used to generate installers for different OS and not for runs-on - os: [ubuntu-20.04, windows-2019] + os: [ubuntu-22.04, windows-2019] arch: [amd64] include: - - os: ubuntu-20.04 + - os: ubuntu-22.04 platform-name: linux installbuilder-name: linux-x64 installer-extension: .run @@ -433,7 +438,7 @@ jobs: # zip artifacts do not mantain executable permission - name: Make executable run: chmod -v +x artifacts/${{ matrix.platform-name }}/${{ env.PROJECT_NAME }}* - if: matrix.os == 'ubuntu-20.04' + if: matrix.os == 'ubuntu-22.04' - name: Rename executable to Arduino_Cloud_Agent run: mv -v artifacts/${{ matrix.platform-name }}/${{ env.PROJECT_NAME }}${{ matrix.extension }} artifacts/${{ matrix.platform-name }}/Arduino_Cloud_Agent${{ matrix.extension }} @@ -446,7 +451,7 @@ jobs: - name: Generate archive run: tar -czvf ArduinoCloudAgent-${GITHUB_REF##*/}-${{ matrix.platform-name }}-${{ matrix.arch }}-installer.tar.gz ArduinoCloudAgent-${GITHUB_REF##*/}-${{ matrix.platform-name }}-${{ matrix.arch }}-installer${{matrix.installer-extension}} - if: matrix.os == 'ubuntu-20.04' + if: matrix.os == 'ubuntu-22.04' - name: Upload artifacts uses: actions/upload-artifact@v4 @@ -601,7 +606,7 @@ jobs: if-no-files-found: error create-release: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 environment: production needs: [build, generate-sign-dmg, sign-windows] diff --git a/.licenses/arduino-create-agent/go/github.com/arduino/go-serial-utils.dep.yml b/.licenses/arduino-create-agent/go/github.com/arduino/go-serial-utils.dep.yml index d80310c77..fb7fa6ea5 100644 --- a/.licenses/arduino-create-agent/go/github.com/arduino/go-serial-utils.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/arduino/go-serial-utils.dep.yml @@ -2,7 +2,7 @@ name: github.com/arduino/go-serial-utils version: v0.1.2 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/arduino/go-serial-utils license: gpl-3.0 licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/arduino/pluggable-discovery-protocol-handler/v2.dep.yml b/.licenses/arduino-create-agent/go/github.com/arduino/pluggable-discovery-protocol-handler/v2.dep.yml index 2fdbca217..0825582ba 100644 --- a/.licenses/arduino-create-agent/go/github.com/arduino/pluggable-discovery-protocol-handler/v2.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/arduino/pluggable-discovery-protocol-handler/v2.dep.yml @@ -1,6 +1,6 @@ --- name: github.com/arduino/pluggable-discovery-protocol-handler/v2 -version: v2.2.0 +version: v2.2.1 type: go summary: Package discovery is a library for handling the Arduino Pluggable-Discovery protocol (https://github.com/arduino/tooling-rfcs/blob/main/RFCs/0002-pluggable-discovery.md#pluggable-discovery-api-via-stdinstdout) diff --git a/.licenses/arduino-create-agent/go/github.com/blang/semver.dep.yml b/.licenses/arduino-create-agent/go/github.com/blang/semver.dep.yml index 3ef4e43fa..39cce428f 100644 --- a/.licenses/arduino-create-agent/go/github.com/blang/semver.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/blang/semver.dep.yml @@ -2,7 +2,7 @@ name: github.com/blang/semver version: v3.5.1+incompatible type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/blang/semver license: mit licenses: @@ -33,3 +33,4 @@ licenses: - sources: README.md text: See [LICENSE](LICENSE) file. notices: [] +... diff --git a/.licenses/arduino-create-agent/go/github.com/creack/goselect.dep.yml b/.licenses/arduino-create-agent/go/github.com/creack/goselect.dep.yml index 2ebe18293..0785cd02c 100644 --- a/.licenses/arduino-create-agent/go/github.com/creack/goselect.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/creack/goselect.dep.yml @@ -2,7 +2,7 @@ name: github.com/creack/goselect version: v0.1.2 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/creack/goselect license: mit licenses: @@ -33,3 +33,4 @@ licenses: - sources: README.md text: Released under the [MIT license](LICENSE). notices: [] +... diff --git a/.licenses/arduino-create-agent/go/github.com/gin-contrib/sse.dep.yml b/.licenses/arduino-create-agent/go/github.com/gin-contrib/sse.dep.yml index 4895be7a5..c888d59ab 100644 --- a/.licenses/arduino-create-agent/go/github.com/gin-contrib/sse.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/gin-contrib/sse.dep.yml @@ -2,7 +2,7 @@ name: github.com/gin-contrib/sse version: v0.1.0 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/gin-contrib/sse license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/binding.dep.yml b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/binding.dep.yml index 6801615fa..a99238ac3 100644 --- a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/binding.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/binding.dep.yml @@ -2,7 +2,7 @@ name: github.com/gin-gonic/gin/binding version: v1.10.0 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/gin-gonic/gin/binding license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/bytesconv.dep.yml b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/bytesconv.dep.yml index c9d7afd9a..97e8d6cb9 100644 --- a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/bytesconv.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/bytesconv.dep.yml @@ -2,7 +2,7 @@ name: github.com/gin-gonic/gin/internal/bytesconv version: v1.10.0 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/gin-gonic/gin/internal/bytesconv license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/json.dep.yml b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/json.dep.yml index 57739599b..2551fb8d9 100644 --- a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/json.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/internal/json.dep.yml @@ -2,7 +2,7 @@ name: github.com/gin-gonic/gin/internal/json version: v1.10.0 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/gin-gonic/gin/internal/json license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/render.dep.yml b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/render.dep.yml index 5b0dc5bbb..deb06fb36 100644 --- a/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/render.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/gin-gonic/gin/render.dep.yml @@ -2,7 +2,7 @@ name: github.com/gin-gonic/gin/render version: v1.10.0 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/gin-gonic/gin/render license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io.dep.yml b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io.dep.yml index a798ca46f..3d65daba3 100644 --- a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io.dep.yml @@ -2,7 +2,7 @@ name: github.com/googollee/go-engine.io version: v0.0.0-20180829091931-e2f255711dcb type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/googollee/go-engine.io license: bsd-3-clause licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/message.dep.yml b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/message.dep.yml index ccf2355f5..55490cf08 100644 --- a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/message.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/message.dep.yml @@ -2,7 +2,7 @@ name: github.com/googollee/go-engine.io/message version: v0.0.0-20180829091931-e2f255711dcb type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/googollee/go-engine.io/message license: bsd-3-clause licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/parser.dep.yml b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/parser.dep.yml index 0a08396a0..718fadade 100644 --- a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/parser.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/parser.dep.yml @@ -2,7 +2,7 @@ name: github.com/googollee/go-engine.io/parser version: v0.0.0-20180829091931-e2f255711dcb type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/googollee/go-engine.io/parser license: bsd-3-clause licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/polling.dep.yml b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/polling.dep.yml index ccc32fe6e..5692db014 100644 --- a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/polling.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/polling.dep.yml @@ -2,7 +2,7 @@ name: github.com/googollee/go-engine.io/polling version: v0.0.0-20180829091931-e2f255711dcb type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/googollee/go-engine.io/polling license: bsd-3-clause licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/transport.dep.yml b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/transport.dep.yml index d48516a8a..430ab5ad5 100644 --- a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/transport.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/transport.dep.yml @@ -2,7 +2,7 @@ name: github.com/googollee/go-engine.io/transport version: v0.0.0-20180829091931-e2f255711dcb type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/googollee/go-engine.io/transport license: bsd-3-clause licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/websocket.dep.yml b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/websocket.dep.yml index 9eb8de2c2..3718a69b2 100644 --- a/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/websocket.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/googollee/go-engine.io/websocket.dep.yml @@ -2,7 +2,7 @@ name: github.com/googollee/go-engine.io/websocket version: v0.0.0-20180829091931-e2f255711dcb type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/googollee/go-engine.io/websocket license: bsd-3-clause licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/h2non/filetype.dep.yml b/.licenses/arduino-create-agent/go/github.com/h2non/filetype.dep.yml index 02102b9ee..ce88ad732 100644 --- a/.licenses/arduino-create-agent/go/github.com/h2non/filetype.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/h2non/filetype.dep.yml @@ -2,7 +2,7 @@ name: github.com/h2non/filetype version: v1.1.3 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/h2non/filetype license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers.dep.yml b/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers.dep.yml index e9421e1f8..e441102a1 100644 --- a/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers.dep.yml @@ -2,7 +2,7 @@ name: github.com/h2non/filetype/matchers version: v1.1.3 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/h2non/filetype/matchers license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers/isobmff.dep.yml b/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers/isobmff.dep.yml index 0a3984965..d18a56f5a 100644 --- a/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers/isobmff.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/h2non/filetype/matchers/isobmff.dep.yml @@ -2,7 +2,7 @@ name: github.com/h2non/filetype/matchers/isobmff version: v1.1.3 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/h2non/filetype/matchers/isobmff license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/h2non/filetype/types.dep.yml b/.licenses/arduino-create-agent/go/github.com/h2non/filetype/types.dep.yml index f8fe41654..6a3e9ff8c 100644 --- a/.licenses/arduino-create-agent/go/github.com/h2non/filetype/types.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/h2non/filetype/types.dep.yml @@ -2,7 +2,7 @@ name: github.com/h2non/filetype/types version: v1.1.3 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/h2non/filetype/types license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/mattn/go-shellwords.dep.yml b/.licenses/arduino-create-agent/go/github.com/mattn/go-shellwords.dep.yml index afff99822..742e6604f 100644 --- a/.licenses/arduino-create-agent/go/github.com/mattn/go-shellwords.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/mattn/go-shellwords.dep.yml @@ -2,7 +2,7 @@ name: github.com/mattn/go-shellwords version: v1.0.12 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/mattn/go-shellwords license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/characters.dep.yml b/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/characters.dep.yml index afddf80f5..59a3269ba 100644 --- a/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/characters.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/characters.dep.yml @@ -2,7 +2,7 @@ name: github.com/pelletier/go-toml/v2/internal/characters version: v2.2.2 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/pelletier/go-toml/v2/internal/characters license: other licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/danger.dep.yml b/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/danger.dep.yml index 5fe64d014..36075df83 100644 --- a/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/danger.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/danger.dep.yml @@ -2,7 +2,7 @@ name: github.com/pelletier/go-toml/v2/internal/danger version: v2.2.2 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/pelletier/go-toml/v2/internal/danger license: other licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/tracker.dep.yml b/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/tracker.dep.yml index 6b73e51e6..954011183 100644 --- a/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/tracker.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/pelletier/go-toml/v2/internal/tracker.dep.yml @@ -2,7 +2,7 @@ name: github.com/pelletier/go-toml/v2/internal/tracker version: v2.2.2 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/pelletier/go-toml/v2/internal/tracker license: other licenses: diff --git a/.licenses/arduino-create-agent/go/github.com/xrash/smetrics.dep.yml b/.licenses/arduino-create-agent/go/github.com/xrash/smetrics.dep.yml index f2795524e..cbd322a2e 100644 --- a/.licenses/arduino-create-agent/go/github.com/xrash/smetrics.dep.yml +++ b/.licenses/arduino-create-agent/go/github.com/xrash/smetrics.dep.yml @@ -2,7 +2,7 @@ name: github.com/xrash/smetrics version: v0.0.0-20170218160415-a3153f7040e9 type: go -summary: +summary: homepage: https://pkg.go.dev/github.com/xrash/smetrics license: mit licenses: diff --git a/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml b/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml index c55d351d0..73d434109 100644 --- a/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml +++ b/.licenses/arduino-create-agent/go/go.bug.st/serial.dep.yml @@ -1,6 +1,6 @@ --- name: go.bug.st/serial -version: v1.6.1 +version: v1.6.4 type: go summary: Package serial is a cross-platform serial library for the go language. homepage: https://pkg.go.dev/go.bug.st/serial @@ -9,7 +9,7 @@ licenses: - sources: LICENSE text: |2+ - Copyright (c) 2014-2023, Cristian Maglie. + Copyright (c) 2014-2024, Cristian Maglie. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -43,7 +43,7 @@ licenses: - sources: README.md text: |- - The software is release under a [BSD 3-clause license] + This software is released under the [BSD 3-clause license]. [contributors]: https://github.com/bugst/go-serial/graphs/contributors [BSD 3-clause license]: https://github.com/bugst/go-serial/blob/master/LICENSE diff --git a/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml b/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml index 7743f09d9..d7b0b63e1 100644 --- a/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml +++ b/.licenses/arduino-create-agent/go/go.bug.st/serial/enumerator.dep.yml @@ -1,16 +1,16 @@ --- name: go.bug.st/serial/enumerator -version: v1.6.1 +version: v1.6.4 type: go summary: Package enumerator is a golang cross-platform library for USB serial port discovery. homepage: https://pkg.go.dev/go.bug.st/serial/enumerator license: bsd-3-clause licenses: -- sources: serial@v1.6.1/LICENSE +- sources: serial@v1.6.4/LICENSE text: |2+ - Copyright (c) 2014-2023, Cristian Maglie. + Copyright (c) 2014-2024, Cristian Maglie. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ licenses: ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- sources: serial@v1.6.1/README.md +- sources: serial@v1.6.4/README.md text: |- - The software is release under a [BSD 3-clause license] + This software is released under the [BSD 3-clause license]. [contributors]: https://github.com/bugst/go-serial/graphs/contributors [BSD 3-clause license]: https://github.com/bugst/go-serial/blob/master/LICENSE diff --git a/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml b/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml index b744d2524..ac5bb6bb1 100644 --- a/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml +++ b/.licenses/arduino-create-agent/go/go.bug.st/serial/unixutils.dep.yml @@ -1,15 +1,15 @@ --- name: go.bug.st/serial/unixutils -version: v1.6.1 +version: v1.6.4 type: go summary: homepage: https://pkg.go.dev/go.bug.st/serial/unixutils license: bsd-3-clause licenses: -- sources: serial@v1.6.1/LICENSE +- sources: serial@v1.6.4/LICENSE text: |2+ - Copyright (c) 2014-2023, Cristian Maglie. + Copyright (c) 2014-2024, Cristian Maglie. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -41,9 +41,9 @@ licenses: ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- sources: serial@v1.6.1/README.md +- sources: serial@v1.6.4/README.md text: |- - The software is release under a [BSD 3-clause license] + This software is released under the [BSD 3-clause license]. [contributors]: https://github.com/bugst/go-serial/graphs/contributors [BSD 3-clause license]: https://github.com/bugst/go-serial/blob/master/LICENSE diff --git a/.licenses/arduino-create-agent/go/golang.org/x/text/internal/language.dep.yml b/.licenses/arduino-create-agent/go/golang.org/x/text/internal/language.dep.yml index 988bad3c9..4a392d8cf 100644 --- a/.licenses/arduino-create-agent/go/golang.org/x/text/internal/language.dep.yml +++ b/.licenses/arduino-create-agent/go/golang.org/x/text/internal/language.dep.yml @@ -2,7 +2,7 @@ name: golang.org/x/text/internal/language version: v0.15.0 type: go -summary: +summary: homepage: https://pkg.go.dev/golang.org/x/text/internal/language license: bsd-3-clause licenses: diff --git a/.licenses/arduino-create-agent/go/gopkg.in/inconshreveable/go-update.v0/download.dep.yml b/.licenses/arduino-create-agent/go/gopkg.in/inconshreveable/go-update.v0/download.dep.yml index 5894a7618..12e0b1dcf 100644 --- a/.licenses/arduino-create-agent/go/gopkg.in/inconshreveable/go-update.v0/download.dep.yml +++ b/.licenses/arduino-create-agent/go/gopkg.in/inconshreveable/go-update.v0/download.dep.yml @@ -2,7 +2,7 @@ name: gopkg.in/inconshreveable/go-update.v0/download version: v0.0.0-20150814200126-d8b0b1d421aa type: go -summary: +summary: homepage: https://pkg.go.dev/gopkg.in/inconshreveable/go-update.v0/download license: apache-2.0 licenses: diff --git a/conn.go b/conn.go index b6e03268c..8c71c54c4 100644 --- a/conn.go +++ b/conn.go @@ -19,6 +19,7 @@ package main import ( "bytes" + "crypto/rsa" "encoding/json" "errors" "fmt" @@ -79,111 +80,114 @@ type Upload struct { var uploadStatusStr = "ProgrammerStatus" -func uploadHandler(c *gin.Context) { - data := new(Upload) - if err := c.BindJSON(data); err != nil { - c.String(http.StatusBadRequest, fmt.Sprintf("err with the payload. %v", err.Error())) - return - } - - log.Printf("%+v %+v %+v %+v %+v %+v", data.Port, data.Board, data.Rewrite, data.Commandline, data.Extra, data.Filename) - - if data.Port == "" { - c.String(http.StatusBadRequest, "port is required") - return - } - - if data.Board == "" { - c.String(http.StatusBadRequest, "board is required") - log.Error("board is required") - return - } - - if !data.Extra.Network { - if data.Signature == "" { - c.String(http.StatusBadRequest, "signature is required") +func uploadHandler(pubKey *rsa.PublicKey) func(*gin.Context) { + return func(c *gin.Context) { + data := new(Upload) + if err := c.BindJSON(data); err != nil { + c.String(http.StatusBadRequest, fmt.Sprintf("err with the payload. %v", err.Error())) return } - if data.Commandline == "" { - c.String(http.StatusBadRequest, "commandline is required for local board") + log.Printf("%+v %+v %+v %+v %+v %+v", data.Port, data.Board, data.Rewrite, data.Commandline, data.Extra, data.Filename) + + if data.Port == "" { + c.String(http.StatusBadRequest, "port is required") return } - err := utilities.VerifyInput(data.Commandline, data.Signature) - - if err != nil { - c.String(http.StatusBadRequest, "signature is invalid") + if data.Board == "" { + c.String(http.StatusBadRequest, "board is required") + log.Error("board is required") return } - } - buffer := bytes.NewBuffer(data.Hex) + if !data.Extra.Network { + if data.Signature == "" { + c.String(http.StatusBadRequest, "signature is required") + return + } - filePath, err := utilities.SaveFileonTempDir(data.Filename, buffer) - if err != nil { - c.String(http.StatusBadRequest, err.Error()) - return - } + if data.Commandline == "" { + c.String(http.StatusBadRequest, "commandline is required for local board") + return + } - tmpdir, err := os.MkdirTemp("", "extrafiles") - if err != nil { - c.String(http.StatusBadRequest, err.Error()) - return - } + err := utilities.VerifyInput(data.Commandline, data.Signature, pubKey) - for _, extraFile := range data.ExtraFiles { - path, err := utilities.SafeJoin(tmpdir, extraFile.Filename) - if err != nil { - c.String(http.StatusBadRequest, err.Error()) - return + if err != nil { + log.WithField("err", err).Error("Error verifying the command") + c.String(http.StatusBadRequest, "signature is invalid") + return + } } - log.Printf("Saving %s on %s", extraFile.Filename, path) - err = os.MkdirAll(filepath.Dir(path), 0744) - if err != nil { - c.String(http.StatusBadRequest, err.Error()) - return - } + buffer := bytes.NewBuffer(data.Hex) - err = os.WriteFile(path, extraFile.Hex, 0644) + filePath, err := utilities.SaveFileonTempDir(data.Filename, buffer) if err != nil { c.String(http.StatusBadRequest, err.Error()) return } - } - if data.Rewrite != "" { - data.Board = data.Rewrite - } - - go func() { - // Resolve commandline - commandline, err := upload.PartiallyResolve(data.Board, filePath, tmpdir, data.Commandline, data.Extra, Tools) + tmpdir, err := os.MkdirTemp("", "extrafiles") if err != nil { - send(map[string]string{uploadStatusStr: "Error", "Msg": err.Error()}) + c.String(http.StatusBadRequest, err.Error()) return } - l := PLogger{Verbose: true} - - // Upload - if data.Extra.Network { - err = errors.New("network upload is not supported anymore, pease use OTA instead") - } else { - send(map[string]string{uploadStatusStr: "Starting", "Cmd": "Serial"}) - err = upload.Serial(data.Port, commandline, data.Extra, l) + for _, extraFile := range data.ExtraFiles { + path, err := utilities.SafeJoin(tmpdir, extraFile.Filename) + if err != nil { + c.String(http.StatusBadRequest, err.Error()) + return + } + log.Printf("Saving %s on %s", extraFile.Filename, path) + + err = os.MkdirAll(filepath.Dir(path), 0744) + if err != nil { + c.String(http.StatusBadRequest, err.Error()) + return + } + + err = os.WriteFile(path, extraFile.Hex, 0644) + if err != nil { + c.String(http.StatusBadRequest, err.Error()) + return + } } - // Handle result - if err != nil { - send(map[string]string{uploadStatusStr: "Error", "Msg": err.Error()}) - return + if data.Rewrite != "" { + data.Board = data.Rewrite } - send(map[string]string{uploadStatusStr: "Done", "Flash": "Ok"}) - }() - c.String(http.StatusAccepted, "") + go func() { + // Resolve commandline + commandline, err := upload.PartiallyResolve(data.Board, filePath, tmpdir, data.Commandline, data.Extra, Tools) + if err != nil { + send(map[string]string{uploadStatusStr: "Error", "Msg": err.Error()}) + return + } + + l := PLogger{Verbose: true} + + // Upload + if data.Extra.Network { + err = errors.New("network upload is not supported anymore, pease use OTA instead") + } else { + send(map[string]string{uploadStatusStr: "Starting", "Cmd": "Serial"}) + err = upload.Serial(data.Port, commandline, data.Extra, l) + } + + // Handle result + if err != nil { + send(map[string]string{uploadStatusStr: "Error", "Msg": err.Error()}) + return + } + send(map[string]string{uploadStatusStr: "Done", "Flash": "Ok"}) + }() + + c.String(http.StatusAccepted, "") + } } // PLogger sends the info from the upload to the websocket diff --git a/globals/globals.go b/globals/globals.go index d7cb09a17..ac4c14666 100644 --- a/globals/globals.go +++ b/globals/globals.go @@ -15,8 +15,15 @@ package globals -// DefaultIndexURL is the default index url var ( - // SignatureKey is the public key used to verify commands and url sent by the builder - SignatureKey = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvc0yZr1yUSen7qmE3cxF\nIE12rCksDnqR+Hp7o0nGi9123eCSFcJ7CkIRC8F+8JMhgI3zNqn4cUEn47I3RKD1\nZChPUCMiJCvbLbloxfdJrUi7gcSgUXrlKQStOKF5Iz7xv1M4XOP3JtjXLGo3EnJ1\npFgdWTOyoSrA8/w1rck4c/ISXZSinVAggPxmLwVEAAln6Itj6giIZHKvA2fL2o8z\nCeK057Lu8X6u2CG8tRWSQzVoKIQw/PKK6CNXCAy8vo4EkXudRutnEYHEJlPkVgPn\n2qP06GI+I+9zKE37iqj0k1/wFaCVXHXIvn06YrmjQw6I0dDj/60Wvi500FuRVpn9\ntwIDAQAB\n-----END PUBLIC KEY-----" + // ArduinoSignaturePubKey is the public key used to verify commands and url sent by the builder + ArduinoSignaturePubKey = `-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvc0yZr1yUSen7qmE3cxF +IE12rCksDnqR+Hp7o0nGi9123eCSFcJ7CkIRC8F+8JMhgI3zNqn4cUEn47I3RKD1 +ZChPUCMiJCvbLbloxfdJrUi7gcSgUXrlKQStOKF5Iz7xv1M4XOP3JtjXLGo3EnJ1 +pFgdWTOyoSrA8/w1rck4c/ISXZSinVAggPxmLwVEAAln6Itj6giIZHKvA2fL2o8z +CeK057Lu8X6u2CG8tRWSQzVoKIQw/PKK6CNXCAy8vo4EkXudRutnEYHEJlPkVgPn +2qP06GI+I+9zKE37iqj0k1/wFaCVXHXIvn06YrmjQw6I0dDj/60Wvi500FuRVpn9 +twIDAQAB +-----END PUBLIC KEY-----` ) diff --git a/go.mod b/go.mod index 82ee10173..3bffc09ed 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/ProtonMail/go-crypto v1.1.0-alpha.5-proton github.com/arduino/go-paths-helper v1.12.1 github.com/arduino/go-serial-utils v0.1.2 - github.com/arduino/pluggable-discovery-protocol-handler/v2 v2.2.0 + github.com/arduino/pluggable-discovery-protocol-handler/v2 v2.2.1 github.com/blang/semver v3.5.1+incompatible github.com/codeclysm/extract/v4 v4.0.0 github.com/gin-contrib/cors v1.7.2 @@ -21,7 +21,7 @@ require ( github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 github.com/stretchr/testify v1.9.0 github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9 - go.bug.st/serial v1.6.1 + go.bug.st/serial v1.6.4 goa.design/goa/v3 v3.16.1 golang.org/x/sys v0.23.0 gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa diff --git a/go.sum b/go.sum index bee2988ac..676649d56 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,8 @@ github.com/arduino/go-properties-orderedmap v1.8.0 h1:wEfa6hHdpezrVOh787OmClsf/K github.com/arduino/go-properties-orderedmap v1.8.0/go.mod h1:DKjD2VXY/NZmlingh4lSFMEYCVubfeArCsGPGDwb2yk= github.com/arduino/go-serial-utils v0.1.2 h1:MRFwME4w/uaVkJ1R+wzz4KSbI9cF9IDVrYorazvjpTk= github.com/arduino/go-serial-utils v0.1.2/go.mod h1:kzIsNPgz8DFAd1sAFKve4ubxrdGcwQ4XzvRLlztsgnE= -github.com/arduino/pluggable-discovery-protocol-handler/v2 v2.2.0 h1:v7og6LpskewFabmaShKVzWXl5MXbmsxaRP3yo4dJta8= -github.com/arduino/pluggable-discovery-protocol-handler/v2 v2.2.0/go.mod h1:1dgblsmK2iBx3L5iNTyRIokeaxbTLUrYiUbHBK6yC3Y= +github.com/arduino/pluggable-discovery-protocol-handler/v2 v2.2.1 h1:Fw8zKj1b/FkcQrWgN7aBw3ubSxpKIUtdANLXvd1Qdzw= +github.com/arduino/pluggable-discovery-protocol-handler/v2 v2.2.1/go.mod h1:1dgblsmK2iBx3L5iNTyRIokeaxbTLUrYiUbHBK6yC3Y= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= @@ -159,8 +159,8 @@ github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9 h1:w8V9v0qVympSF6GjdjIyeqR7+EVhAF9CBQmkmW7Zw0w= github.com/xrash/smetrics v0.0.0-20170218160415-a3153f7040e9/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -go.bug.st/serial v1.6.1 h1:VSSWmUxlj1T/YlRo2J104Zv3wJFrjHIl/T3NeruWAHY= -go.bug.st/serial v1.6.1/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE= +go.bug.st/serial v1.6.4 h1:7FmqNPgVp3pu2Jz5PoPtbZ9jJO5gnEnZIvnI1lzve8A= +go.bug.st/serial v1.6.4/go.mod h1:nofMJxTeNVny/m6+KaafC6vJGj3miwQZ6vW4BZUGJPI= goa.design/goa/v3 v3.16.1 h1:yZwbKrfMpE8+sz0uf+n+BtArVOFQ0kNSC0twQKwQb04= goa.design/goa/v3 v3.16.1/go.mod h1:Yd42LR0PYDbHSbsbF3vNd4YY/O+LG20Jb7+IyNdkQic= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= diff --git a/main.go b/main.go index 1ca857b02..41f824b1b 100755 --- a/main.go +++ b/main.go @@ -81,7 +81,7 @@ var ( logDump = iniConf.String("log", "off", "off = (default)") origins = iniConf.String("origins", "", "Allowed origin list for CORS") portsFilterRegexp = iniConf.String("regex", "usb|acm|com", "Regular expression to filter serial port list") - signatureKey = iniConf.String("signatureKey", globals.SignatureKey, "Pem-encoded public key to verify signed commandlines") + signatureKey = iniConf.String("signatureKey", globals.ArduinoSignaturePubKey, "Pem-encoded public key to verify signed commandlines") updateURL = iniConf.String("updateUrl", "", "") verbose = iniConf.Bool("v", true, "show debug logging") crashreport = iniConf.Bool("crashreport", false, "enable crashreport logging") @@ -278,9 +278,17 @@ func loop() { } } + if signatureKey == nil || len(*signatureKey) == 0 { + log.Panicf("signature public key should be set") + } + signaturePubKey, err := utilities.ParseRsaPublicKey([]byte(*signatureKey)) + if err != nil { + log.Panicf("cannot parse signature key '%s'. %s", *signatureKey, err) + } + // Instantiate Index and Tools Index = index.Init(*indexURL, config.GetDataDir()) - Tools = tools.New(config.GetDataDir(), Index, logger) + Tools = tools.New(config.GetDataDir(), Index, logger, signaturePubKey) // see if we are supposed to wait 5 seconds if *isLaunchSelf { @@ -454,7 +462,7 @@ func loop() { r.LoadHTMLFiles("templates/nofirefox.html") r.GET("/", homeHandler) - r.POST("/upload", uploadHandler) + r.POST("/upload", uploadHandler(signaturePubKey)) r.GET("/socket.io/", socketHandler) r.POST("/socket.io/", socketHandler) r.Handle("WS", "/socket.io/", socketHandler) @@ -464,7 +472,7 @@ func loop() { r.POST("/update", updateHandler) // Mount goa handlers - goa := v2.Server(config.GetDataDir().String(), Index) + goa := v2.Server(config.GetDataDir().String(), Index, signaturePubKey) r.Any("/v2/*path", gin.WrapH(goa)) go func() { diff --git a/main_test.go b/main_test.go index d6f23fcec..1387fd221 100644 --- a/main_test.go +++ b/main_test.go @@ -30,8 +30,10 @@ import ( "github.com/arduino/arduino-create-agent/config" "github.com/arduino/arduino-create-agent/gen/tools" + "github.com/arduino/arduino-create-agent/globals" "github.com/arduino/arduino-create-agent/index" "github.com/arduino/arduino-create-agent/upload" + "github.com/arduino/arduino-create-agent/utilities" v2 "github.com/arduino/arduino-create-agent/v2" "github.com/gin-gonic/gin" "github.com/stretchr/testify/require" @@ -54,7 +56,7 @@ func TestValidSignatureKey(t *testing.T) { func TestUploadHandlerAgainstEvilFileNames(t *testing.T) { r := gin.New() - r.POST("/", uploadHandler) + r.POST("/", uploadHandler(utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey)))) ts := httptest.NewServer(r) uploadEvilFileName := Upload{ @@ -90,7 +92,7 @@ func TestUploadHandlerAgainstEvilFileNames(t *testing.T) { func TestUploadHandlerAgainstBase64WithoutPaddingMustFail(t *testing.T) { r := gin.New() - r.POST("/", uploadHandler) + r.POST("/", uploadHandler(utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey)))) ts := httptest.NewServer(r) defer ts.Close() @@ -119,7 +121,7 @@ func TestInstallToolV2(t *testing.T) { Index := index.Init(indexURL, config.GetDataDir()) r := gin.New() - goa := v2.Server(config.GetDataDir().String(), Index) + goa := v2.Server(config.GetDataDir().String(), Index, utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) r.Any("/v2/*path", gin.WrapH(goa)) ts := httptest.NewServer(r) @@ -213,7 +215,7 @@ func TestInstalledHead(t *testing.T) { Index := index.Init(indexURL, config.GetDataDir()) r := gin.New() - goa := v2.Server(config.GetDataDir().String(), Index) + goa := v2.Server(config.GetDataDir().String(), Index, utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) r.Any("/v2/*path", gin.WrapH(goa)) ts := httptest.NewServer(r) diff --git a/serial.go b/serial.go index 64e5b8f7f..1a43f3644 100755 --- a/serial.go +++ b/serial.go @@ -31,7 +31,7 @@ import ( type serialhub struct { // Opened serial ports. - ports map[*serport]bool + ports map[string]*serport mu sync.Mutex } @@ -60,7 +60,7 @@ type SpPortItem struct { var serialPorts SerialPortList var sh = serialhub{ - ports: make(map[*serport]bool), + ports: make(map[string]*serport), } // Register serial ports from the connections. @@ -68,7 +68,7 @@ func (sh *serialhub) Register(port *serport) { sh.mu.Lock() //log.Print("Registering a port: ", p.portConf.Name) h.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + ",\"BufferType\":\"" + port.BufferType + "\"}") - sh.ports[port] = true + sh.ports[port.portName] = port sh.mu.Unlock() } @@ -77,7 +77,7 @@ func (sh *serialhub) Unregister(port *serport) { sh.mu.Lock() //log.Print("Unregistering a port: ", p.portConf.Name) h.broadcastSys <- []byte("{\"Cmd\":\"Close\",\"Desc\":\"Got unregister/close on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + "}") - delete(sh.ports, port) + delete(sh.ports, port.portName) close(port.sendBuffered) close(port.sendNoBuf) sh.mu.Unlock() @@ -86,15 +86,8 @@ func (sh *serialhub) Unregister(port *serport) { func (sh *serialhub) FindPortByName(portname string) (*serport, bool) { sh.mu.Lock() defer sh.mu.Unlock() - - for port := range sh.ports { - if strings.EqualFold(port.portConf.Name, portname) { - // we found our port - //spHandlerClose(port) - return port, true - } - } - return nil, false + port, ok := sh.ports[portname] + return port, ok } // List broadcasts a Json representation of the ports found diff --git a/serialport.go b/serialport.go index a11483f63..b3418fe5d 100755 --- a/serialport.go +++ b/serialport.go @@ -20,6 +20,8 @@ import ( "encoding/base64" "io" "strconv" + "sync" + "sync/atomic" "time" "unicode/utf8" @@ -43,7 +45,7 @@ type serport struct { // Keep track of whether we're being actively closed // just so we don't show scary error messages - isClosing bool + isClosing atomic.Bool isClosingDueToError bool @@ -85,7 +87,7 @@ func (p *serport) reader(buftype string) { bufferPart := serialBuffer[:n] //if we detect that port is closing, break out of this for{} loop. - if p.isClosing { + if p.isClosing.Load() { strmsg := "Shutting down reader on " + p.portConf.Name log.Println(strmsg) h.broadcastSys <- []byte(strmsg) @@ -272,7 +274,13 @@ func (p *serport) writerRaw() { h.broadcastSys <- []byte(msgstr) } +// This lock is used to prevent multiple threads from trying to open the same port at the same time. +// It presents issues with the serial port driver on some OS's: https://github.com/arduino/arduino-create-agent/issues/1031 +var spHandlerOpenLock sync.Mutex + func spHandlerOpen(portname string, baud int, buftype string) { + spHandlerOpenLock.Lock() + defer spHandlerOpenLock.Unlock() log.Print("Inside spHandler") @@ -294,11 +302,14 @@ func spHandlerOpen(portname string, baud int, buftype string) { sp, err := serial.Open(portname, mode) log.Print("Just tried to open port") if err != nil { - //log.Fatal(err) - log.Print("Error opening port " + err.Error()) - //h.broadcastSys <- []byte("Error opening port. " + err.Error()) - h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Error opening port. " + err.Error() + "\",\"Port\":\"" + conf.Name + "\",\"Baud\":" + strconv.Itoa(conf.Baud) + "}") - + existingPort, ok := sh.FindPortByName(portname) + if ok && existingPort.portConf.Baud == baud && existingPort.BufferType == buftype { + log.Print("Port already opened") + h.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Port already opened.\",\"Port\":\"" + existingPort.portConf.Name + "\",\"Baud\":" + strconv.Itoa(existingPort.portConf.Baud) + ",\"BufferType\":\"" + existingPort.BufferType + "\"}") + } else { + log.Print("Error opening port " + err.Error()) + h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Error opening port. " + err.Error() + "\",\"Port\":\"" + conf.Name + "\",\"Baud\":" + strconv.Itoa(conf.Baud) + "}") + } return } log.Print("Opened port successfully") @@ -330,7 +341,6 @@ func spHandlerOpen(portname string, baud int, buftype string) { p.bufferwatcher = bw sh.Register(p) - defer sh.Unregister(p) serialPorts.MarkPortAsOpened(portname) serialPorts.List() @@ -341,14 +351,17 @@ func spHandlerOpen(portname string, baud int, buftype string) { go p.writerNoBuf() // this is thread to send to serial port but with base64 decoding go p.writerRaw() - - p.reader(buftype) - - serialPorts.List() + // this is the thread that reads from the serial port + go func() { + p.reader(buftype) + serialPorts.List() + sh.Unregister(p) + }() } func (p *serport) Close() { - p.isClosing = true + p.isClosing.Store(true) + p.bufferwatcher.Close() p.portIo.Close() serialPorts.MarkPortAsClosed(p.portName) diff --git a/tools/download_test.go b/tools/download_test.go index 7cf2fab0d..96a105fd7 100644 --- a/tools/download_test.go +++ b/tools/download_test.go @@ -21,7 +21,9 @@ import ( "testing" "time" + "github.com/arduino/arduino-create-agent/globals" "github.com/arduino/arduino-create-agent/index" + "github.com/arduino/arduino-create-agent/utilities" "github.com/arduino/arduino-create-agent/v2/pkgs" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" @@ -128,7 +130,7 @@ func TestDownload(t *testing.T) { IndexFile: *paths.New("testdata", "test_tool_index.json"), LastRefresh: time.Now(), } - testTools := New(tempDirPath, &testIndex, func(msg string) { t.Log(msg) }) + testTools := New(tempDirPath, &testIndex, func(msg string) { t.Log(msg) }, utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) for _, tc := range testCases { t.Run(tc.name+"-"+tc.version, func(t *testing.T) { @@ -175,7 +177,7 @@ func TestCorruptedInstalled(t *testing.T) { defer fileJSON.Close() _, err = fileJSON.Write([]byte("Hello")) require.NoError(t, err) - testTools := New(tempDirPath, &testIndex, func(msg string) { t.Log(msg) }) + testTools := New(tempDirPath, &testIndex, func(msg string) { t.Log(msg) }, utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) // Download the tool err = testTools.Download("arduino-test", "avrdude", "6.3.0-arduino17", "keep") require.NoError(t, err) diff --git a/tools/tools.go b/tools/tools.go index 5cecc5089..f371126b5 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -16,6 +16,7 @@ package tools import ( + "crypto/rsa" "encoding/json" "path/filepath" "strings" @@ -55,14 +56,14 @@ type Tools struct { // The New functions accept the directory to use to host the tools, // an index (used to download the tools), // and a logger to log the operations -func New(directory *paths.Path, index *index.Resource, logger func(msg string)) *Tools { +func New(directory *paths.Path, index *index.Resource, logger func(msg string), signPubKey *rsa.PublicKey) *Tools { t := &Tools{ directory: directory, index: index, logger: logger, installed: map[string]string{}, mutex: sync.RWMutex{}, - tools: pkgs.New(index, directory.String(), "replace"), + tools: pkgs.New(index, directory.String(), "replace", signPubKey), } _ = t.readMap() return t diff --git a/utilities/utilities.go b/utilities/utilities.go index 5979732d4..662672da7 100644 --- a/utilities/utilities.go +++ b/utilities/utilities.go @@ -30,8 +30,6 @@ import ( "os/exec" "path/filepath" "strings" - - "github.com/arduino/arduino-create-agent/globals" ) // SaveFileonTempDir creates a temp directory and saves the file data as the @@ -131,23 +129,44 @@ func SafeJoin(parent, subdir string) (string, error) { return res, nil } -// VerifyInput will verify an input against a signature +// VerifyInput will verify an input against a signature using the public key. // A valid signature is indicated by returning a nil error. -func VerifyInput(input string, signature string) error { +func VerifyInput(input string, signature string, pubKey *rsa.PublicKey) error { sign, _ := hex.DecodeString(signature) - block, _ := pem.Decode([]byte(globals.SignatureKey)) + h := sha256.New() + h.Write([]byte(input)) + d := h.Sum(nil) + return rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, d, sign) +} + +// ParseRsaPublicKey parses a public key in PEM format and returns the rsa.PublicKey object. +// Returns an error if the key is invalid. +func ParseRsaPublicKey(key []byte) (*rsa.PublicKey, error) { + block, _ := pem.Decode(key) if block == nil { - return errors.New("invalid key") + return nil, errors.New("invalid key") } - key, err := x509.ParsePKIXPublicKey(block.Bytes) + + parsedKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return err + return nil, err } - rsaKey := key.(*rsa.PublicKey) - h := sha256.New() - h.Write([]byte(input)) - d := h.Sum(nil) - return rsa.VerifyPKCS1v15(rsaKey, crypto.SHA256, d, sign) + + publicKey, ok := parsedKey.(*rsa.PublicKey) + if !ok { + return nil, fmt.Errorf("not an rsa key") + } + return publicKey, nil +} + +// MustParseRsaPublicKey parses a public key in PEM format and returns the rsa.PublicKey object. +// Panics if the key is invalid. +func MustParseRsaPublicKey(key []byte) *rsa.PublicKey { + parsedKey, err := ParseRsaPublicKey(key) + if err != nil { + panic(err) + } + return parsedKey } // UserPrompt executes an osascript and returns the pressed button diff --git a/v2/http.go b/v2/http.go index 390ec3989..2b47b93a8 100644 --- a/v2/http.go +++ b/v2/http.go @@ -17,6 +17,7 @@ package v2 import ( "context" + "crypto/rsa" "encoding/json" "net/http" @@ -31,7 +32,7 @@ import ( ) // Server is the actual server -func Server(directory string, index *index.Resource) http.Handler { +func Server(directory string, index *index.Resource, pubKey *rsa.PublicKey) http.Handler { mux := goahttp.NewMuxer() // Instantiate logger @@ -40,7 +41,7 @@ func Server(directory string, index *index.Resource) http.Handler { logAdapter := LogAdapter{Logger: logger} // Mount tools - toolsSvc := pkgs.New(index, directory, "replace") + toolsSvc := pkgs.New(index, directory, "replace", pubKey) toolsEndpoints := toolssvc.NewEndpoints(toolsSvc) toolsServer := toolssvr.New(toolsEndpoints, mux, CustomRequestDecoder, goahttp.ResponseEncoder, errorHandler(logger), nil) toolssvr.Mount(mux, toolsServer) diff --git a/v2/pkgs/tools.go b/v2/pkgs/tools.go index f09dc3f0a..7f34e3d08 100644 --- a/v2/pkgs/tools.go +++ b/v2/pkgs/tools.go @@ -18,6 +18,7 @@ package pkgs import ( "bytes" "context" + "crypto/rsa" "crypto/sha256" "encoding/hex" "encoding/json" @@ -58,23 +59,25 @@ var ( // // It requires an Index Resource to search for tools type Tools struct { - index *index.Resource - folder string - behaviour string - installed map[string]string - mutex sync.RWMutex + index *index.Resource + folder string + behaviour string + installed map[string]string + mutex sync.RWMutex + verifySignaturePubKey *rsa.PublicKey // public key used to verify the signature of a command sent to the boards } // New will return a Tool object, allowing the caller to execute operations on it. // The New function will accept an index as parameter (used to download the indexes) // and a folder used to download the indexes -func New(index *index.Resource, folder, behaviour string) *Tools { +func New(index *index.Resource, folder, behaviour string, verifySignaturePubKey *rsa.PublicKey) *Tools { t := &Tools{ - index: index, - folder: folder, - behaviour: behaviour, - installed: map[string]string{}, - mutex: sync.RWMutex{}, + index: index, + folder: folder, + behaviour: behaviour, + installed: map[string]string{}, + mutex: sync.RWMutex{}, + verifySignaturePubKey: verifySignaturePubKey, } t.readInstalled() return t @@ -166,7 +169,7 @@ func (t *Tools) Install(ctx context.Context, payload *tools.ToolPayload) (*tools //if URL is defined and is signed we verify the signature and override the name, payload, version parameters if payload.URL != nil && payload.Signature != nil && payload.Checksum != nil { - err := utilities.VerifyInput(*payload.URL, *payload.Signature) + err := utilities.VerifyInput(*payload.URL, *payload.Signature, t.verifySignaturePubKey) if err != nil { return nil, err } diff --git a/v2/pkgs/tools_test.go b/v2/pkgs/tools_test.go index edd575fc8..7bf0ff0e3 100644 --- a/v2/pkgs/tools_test.go +++ b/v2/pkgs/tools_test.go @@ -25,7 +25,9 @@ import ( "github.com/arduino/arduino-create-agent/config" "github.com/arduino/arduino-create-agent/gen/tools" + "github.com/arduino/arduino-create-agent/globals" "github.com/arduino/arduino-create-agent/index" + "github.com/arduino/arduino-create-agent/utilities" "github.com/arduino/arduino-create-agent/v2/pkgs" "github.com/arduino/go-paths-helper" "github.com/stretchr/testify/require" @@ -45,7 +47,7 @@ func TestTools(t *testing.T) { // Instantiate Index Index := index.Init(indexURL, config.GetDataDir()) - service := pkgs.New(Index, tmp, "replace") + service := pkgs.New(Index, tmp, "replace", utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) ctx := context.Background() @@ -126,7 +128,7 @@ func TestEvilFilename(t *testing.T) { // Instantiate Index Index := index.Init(indexURL, config.GetDataDir()) - service := pkgs.New(Index, tmp, "replace") + service := pkgs.New(Index, tmp, "replace", utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) ctx := context.Background() @@ -195,7 +197,7 @@ func TestInstalledHead(t *testing.T) { // Instantiate Index Index := index.Init(indexURL, config.GetDataDir()) - service := pkgs.New(Index, tmp, "replace") + service := pkgs.New(Index, tmp, "replace", utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) ctx := context.Background() @@ -216,7 +218,7 @@ func TestInstall(t *testing.T) { LastRefresh: time.Now(), } - tool := pkgs.New(testIndex, tmp, "replace") + tool := pkgs.New(testIndex, tmp, "replace", utilities.MustParseRsaPublicKey([]byte(globals.ArduinoSignaturePubKey))) ctx := context.Background()