diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index c4b97fe..c7c3a42 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -109,5 +109,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: name: nightly + tag_name: nightly files: artifacts/riotpot.zip prerelease: true diff --git a/.gitignore b/.gitignore index 78a0bba..015723f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,6 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - # Test binary, built with `go test -c` *.test -# Production binary folder -bin/ - # Output of the go coverage tool, specifically when used with LiteIDE *.out @@ -22,16 +12,13 @@ bin/ .vscode/ .DS_Store .dccache +.iac-data ## VSCode workspace file workspace*.code-* -# Vendor folder +# Transit folders /vendor/ - -# Plugins -*.so - -# TCPdump +/bin/ /tcpdump/ # whatever the rules are, include all the `.md` files diff --git a/Makefile b/Makefile index 7cb81a4..67ba800 100644 --- a/Makefile +++ b/Makefile @@ -4,10 +4,7 @@ SHELL := /bin/bash APPNAME=riotpot DOCKER=build/docker/ PLUGINS_DIR=pkg/plugin -EXCLUDE_PLUGINS= sshd - -## -exclude_plugins_list := $(subst ., ,$(EXCLUDE_PLUGINS)) +EXCLUDE_PLUGINS= modbusd coapd mqttd # docker cmd below .PHONY: docker-build-doc docker-doc-up up down up-all build build-plugins build-all ui @@ -23,9 +20,9 @@ up-all: riotpot-doc riotpot-up build: - go build -gcflags='all=-N -l' -o ./bin/ ./cmd/riotpot/. + @go build -gcflags='all=-N -l' -o ./bin/ ./cmd/riotpot/. build-plugins: $(PLUGINS_DIR)/* - exclude=${exclude_plugins_list}; \ + @IFS=' ' read -r -a exclude <<< "${EXCLUDE_PLUGINS}"; \ for folder in $^ ; do \ result=$${folder%%+(/)}; \ result=$${result##*/}; \ diff --git a/README.md b/README.md index d771c56..892ee91 100644 --- a/README.md +++ b/README.md @@ -127,8 +127,8 @@ It is important to keep the internal folder structure for RIoTPot to work as int 1. First, download the release of your choice from the [releases](https://github.com/aau-network-security/riotpot/releases) page. Choose the one you need for your Operative System (OS). 2. Extact the `riotpot` folder. 3. Run the `riotpot` binary. This will start RIoTPot with the API enabled, all the plugins ready to use, and the UI server. - - The UI is accessible through the address `localhost:3000` or `local.riotpot.ui` - - The API is accessible through the address `localhost:2022/api/swagger` or `local.riotpot.hp/api/swagger` + - The UI is accessible through the address `localhost:3000` + - The API is accessible through the address `localhost:2022/api/swagger` @@ -254,4 +254,7 @@ The container can be setup in three simple steps: docker-compose -p riotpot -f build/docker/docker-compose.yaml up -d --build ``` +> **_Info:_** Using Docker has it's own perks, such as minglin with the DNS without touching your local files. +> You can now reach the API at `http://riotpot.hp:2022/api/swagger` and the ui at `http://riotpot.ui:3000` + diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile.riotpot similarity index 95% rename from build/docker/Dockerfile rename to build/docker/Dockerfile.riotpot index 375634c..bc9db94 100644 --- a/build/docker/Dockerfile +++ b/build/docker/Dockerfile.riotpot @@ -38,6 +38,8 @@ WORKDIR /riotpot # Copy the dependencies into the image COPY --from=builder /riotpot/bin/ ./ + +# API, required for the UI. EXPOSE 2022 -ENTRYPOINT ["./riotpot"] \ No newline at end of file +CMD ["./riotpot"] \ No newline at end of file diff --git a/build/docker/docker-compose.test.yaml b/build/docker/docker-compose.test.yaml deleted file mode 100644 index e9a9969..0000000 --- a/build/docker/docker-compose.test.yaml +++ /dev/null @@ -1,33 +0,0 @@ -x-protocol: - &protocol - depends_on: - - riotpot - networks: - honeypot: - default: - -services: - riotpot: - container_name: riotpot - build: - context: ../.. - dockerfile: ./build/docker/Dockerfile - restart: always # restart riotpot when it crashes - env_file: - - ../../build/env/.env - ports: - - "2022:2022" - - "8080:8080" - networks: - honeypot: - default: - - http: - image: httpd - container_name: http - ports: - - "80:80" - <<: *protocol - -networks: - honeypot: \ No newline at end of file diff --git a/build/docker/docker-compose.yaml b/build/docker/docker-compose.yaml index 07bb2d9..1e704e4 100644 --- a/build/docker/docker-compose.yaml +++ b/build/docker/docker-compose.yaml @@ -26,7 +26,7 @@ services: container_name: tcpdump network_mode: "host" volumes: - - ../tcpdump:/tcpdump + - ../../tcpdump:/tcpdump # Run tcdump in autorotating mode, with gzip compression # The files will be rotated every 24h or 500MB and named # after the timestamp when the file is created. @@ -46,23 +46,23 @@ services: container_name: riotpot build: context: ../.. - dockerfile: ./build/docker/Dockerfile + dockerfile: ./build/docker/Dockerfile.riotpot restart: always # restart riotpot when it crashes ports: # Ports under 60 might see errors when unquoted # https://stackoverflow.com/questions/58810789/quotes-on-docker-compose-yml-ports-make-any-difference - "7:7" - # - "22:22" + - "22:22" - "23:23" - # - "80:80" + - "80:80" - "502:502" - "1883:1883" - - "2022:2022" # API, Required for the UI + - "2022:2022" # Required for the REST API - "27017:27017" - "5683:5683" - "8080:8080" - env_file: - - ../../build/env/.env + environment: + - API_HOST=0.0.0.0 networks: honeypot: default: diff --git a/build/env/.env b/build/env/.env deleted file mode 100644 index 0e50e79..0000000 --- a/build/env/.env +++ /dev/null @@ -1,40 +0,0 @@ -# +------------------+ -# Place here the environment variables values with which you -# want to run riotpot. -# This variables will replace the configuration used on runtime, -# and any previously stored configuration. -# +------------------+ -# +------------------+ - -# Boolean-like. This variable defines if you rather allow the honeypot -# to load all the services available in both the configuration -# file and installed plugins. -AUTOD=true - -# Fill only if AUTOD is set to a falsy value. -# Place a comma separated list of emulators that you want -# riotpot to start when initialised. -## NOTE: RIoTPot is *always* run in hybrid mode! -## append a `-c` to the name when using a containerised version -## Example: `http-c` -START= - -# +------------------+ DB -# Here you can find the list of variables related to the database -# that will be used to store the data generated by riotpot -# +------------------+ DB - -# Place here the name that will be used for the database -# By default, riotpot will call it `default` -DB_NAME=db - -# Username and password used to log the information -DB_USER=user -DB_PASS=password - -# Host and Port in where the database is located -DB_HOST=database -DB_PORT=27017 - -# +------------------+ DB -API_HOST=0.0.0.0 diff --git a/cmd/riotpot/flags.go b/cmd/riotpot/flags.go index 3288aad..edcab82 100644 --- a/cmd/riotpot/flags.go +++ b/cmd/riotpot/flags.go @@ -7,6 +7,7 @@ package main import ( "flag" "fmt" + "strings" "time" "github.com/gin-contrib/cors" @@ -17,7 +18,7 @@ import ( "github.com/riotpot/api/service" "github.com/riotpot/internal/globals" "github.com/riotpot/internal/logger" - "github.com/riotpot/pkg" + "github.com/riotpot/internal/plugins" "github.com/rs/zerolog" _ "github.com/riotpot/statik" @@ -36,12 +37,13 @@ var ( ) var ( - debug = flag.Bool("debug", true, "Set log level to debug") - runApi = flag.Bool("api", true, "Whether to start the API") - plugins = flag.Bool("plugins", true, "Whether to load the low-interaction honeypot plugins") + debug = flag.Bool("debug", true, "Set log level to debug") + runApi = flag.Bool("api", true, "Whether to start the API") + loadPlugins = flag.Bool("plugins", true, "Whether to load the low-interaction honeypot plugins") + allowedHosts = flag.String("whitelist", "http://127.0.0.1,http://localhost:3000", "List of allowed hosts to contact the API") ) -func setupApi() *gin.Engine { +func setupApi(allowedHosts []string) *gin.Engine { // Create a router router := gin.Default() @@ -50,7 +52,7 @@ func setupApi() *gin.Engine { // - Credentials share // - Preflight requests cached for 12 hours router.Use(cors.New(cors.Config{ - AllowOrigins: []string{"http://localhost:3000", "http://127.0.0.1", "http://0.0.0.0"}, // TODO: Change this to wherever the front-end is located! + AllowOrigins: allowedHosts, AllowMethods: []string{"OPTIONS", "PUT", "PATCH", "GET", "DELETE"}, AllowHeaders: []string{"Origin", "Content-Type"}, ExposeHeaders: []string{"Content-Length"}, @@ -71,7 +73,6 @@ func setupApi() *gin.Engine { } // Serve the Swagger UI files in the root of the api - // TODO: [7/24/2022] Use Pakr or Statik to bundle non-golang files into the binary root.StaticFS("swagger", statikFS) return router @@ -84,14 +85,17 @@ func ParseFlags() { } // Load the plugins - if *plugins { - pkg.LoadPlugins() + if *loadPlugins { + plugins.LoadPlugins() } // Starts the API if *runApi { // Serve the API - api := setupApi() - api.Run(fmt.Sprintf("%s:%s", globals.ApiHost, globals.ApiPort)) + whitelist := strings.Split(*allowedHosts, ",") + api := setupApi(whitelist) + + apiAddress := fmt.Sprintf("%s:%s", globals.ApiHost, globals.ApiPort) + api.Run(apiAddress) } } diff --git a/configs/configuration.yml b/configs/configuration.yml deleted file mode 100644 index 097ee66..0000000 --- a/configs/configuration.yml +++ /dev/null @@ -1,30 +0,0 @@ ---- -# RiotPot configuration file. -# This file can be used as a template for further implementations and as a record of -# documentation for internal structure when in doubt on usage. -riotpot: - # The name of the services is the name of the folder in which the plugin - # is stored, inside the `pkg/` folder. - # Example: - # * if the plugin is stored in: `pkg/telnetd` - # * then place: `- telnetd` - - # Contains a list of available services in the application. - # This gives the user the ability to navigate or load - # just the emulators that appear in this list, wether or not - # the emulator plugin appears in the binary. - # - # Add here the emulator plugins you have included on the binary. - emulators: - - httpd - - echod - - sshd - - telnetd - - mqttd - - coapd - - modbusd - - # `start` contains a list of services desired to be run - # on-start variable used in Riotpot core on runtime only! - # For all the services leave it empty - start: [] diff --git a/configs/plugin.go b/docs/plugin.template similarity index 100% rename from configs/plugin.go rename to docs/plugin.template diff --git a/go.mod b/go.mod index f7594a6..f53ab7a 100644 --- a/go.mod +++ b/go.mod @@ -9,8 +9,7 @@ require ( github.com/stretchr/testify v1.8.1 github.com/traetox/pty v0.0.0-20141209045113-df6c8cd2e0e6 github.com/xiegeo/modbusone v1.0.1 - go.mongodb.org/mongo-driver v1.11.0 - golang.org/x/crypto v0.1.0 + golang.org/x/crypto v0.5.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -18,44 +17,36 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/dsnet/golib/memfile v1.0.0 // indirect github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.11.1 // indirect - github.com/goccy/go-json v0.9.11 // indirect + github.com/goccy/go-json v0.10.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/montanaflynn/stats v0.6.6 // indirect - github.com/pelletier/go-toml/v2 v2.0.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pion/dtls/v2 v2.1.5 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/udp v0.1.1 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/plgd-dev/kit/v2 v2.0.0-20211006190727-057b33161b90 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/ugorji/go/codec v1.2.7 // indirect - github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.1 // indirect - github.com/xdg-go/stringprep v1.0.3 // indirect - golang.org/x/text v0.4.0 // indirect + github.com/ugorji/go/codec v1.2.8 // indirect + golang.org/x/text v0.6.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) require ( - github.com/gin-gonic/gin v1.8.1 - github.com/golang/snappy v0.0.4 // indirect - github.com/klauspost/compress v1.15.12 // indirect + github.com/gin-gonic/gin v1.8.2 github.com/mattn/go-colorable v0.1.13 // indirect - github.com/pion/transport v0.13.1 // indirect + github.com/pion/transport v0.14.1 // indirect github.com/rakyll/statik v0.1.7 github.com/rs/zerolog v1.28.0 - github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect go.uber.org/atomic v1.10.0 // indirect - golang.org/x/exp v0.0.0-20221106115401-f9659909a136 - golang.org/x/net v0.1.0 // indirect + golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a + golang.org/x/net v0.5.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.2.0 // indirect + golang.org/x/sys v0.4.0 // indirect ) diff --git a/go.sum b/go.sum index dea03e9..c46a7e7 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,9 @@ github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0 github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= +github.com/gin-gonic/gin v1.8.2 h1:UzKToD9/PoFj/V4rvlKqTRKnQYyz8Sc1MJlv4JHPtvY= +github.com/gin-gonic/gin v1.8.2/go.mod h1:qw5AYuDrzRTnhvusDsrov+fDIxp9Dleuu12h8nfB398= github.com/go-acme/lego v2.7.2+incompatible/go.mod h1:yzMNe9CasVUhkquNvti5nAtPmG94USbYxYrZfTkIn0M= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -37,8 +38,9 @@ github.com/go-ocf/go-coap/v2 v2.0.4-0.20200728125043-f38b86f047a7/go.mod h1:X9wV github.com/go-ocf/kit v0.0.0-20200728130040-4aebdb6982bc/go.mod h1:TIsoMT/iB7t9P6ahkcOnsmvS83SIJsv9qXRfz/yLf6M= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= @@ -46,8 +48,8 @@ github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJ github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= -github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.0 h1:mXKd9Qw4NuzShiRlOXKews24ufknHO7gx30lsDyokKA= +github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= @@ -64,14 +66,10 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -88,9 +86,6 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -114,23 +109,21 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ= -github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/panjf2000/ants/v2 v2.4.3/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= -github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= +github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pion/dtls/v2 v2.0.1-0.20200503085337-8e86b3a7d585/go.mod h1:/GahSOC8ZY/+17zkaGJIG4OUkSGAcZu/N/g3roBOCkM= github.com/pion/dtls/v2 v2.0.10-0.20210502094952-3dc563b9aede/go.mod h1:86wv5dgx2J/z871nUR+5fTTY9tISLUlo+C5Gm86r1Hs= github.com/pion/dtls/v2 v2.1.5 h1:jlh2vtIyUBShchoTDqpCCqiYCyRFJ/lvf/gQ8TALs+c= @@ -141,13 +134,12 @@ github.com/pion/transport v0.10.0/go.mod h1:BnHnUipd0rZQyTVB2SBGojFHT9CBt5C5TcsJ github.com/pion/transport v0.12.2/go.mod h1:N3+vZQD9HlDP5GWkZ85LohxNsDcNgofQmyL6ojX5d8Q= github.com/pion/transport v0.12.3/go.mod h1:OViWW9SP2peE/HbwBvARicmAVnesphkNkCVZIWJ6q9A= github.com/pion/transport v0.13.0/go.mod h1:yxm9uXpK9bpBBWkITk13cLo1y5/ur5VQpG22ny6EP7g= -github.com/pion/transport v0.13.1 h1:/UH5yLeQtwm2VZIPjxwnNFxjS4DFhyLfS4GlfuKUzfA= -github.com/pion/transport v0.13.1/go.mod h1:EBxbqzyv+ZrmDb82XswEE0BjfQFtuw1Nu6sjnjWCsGg= +github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= +github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o= github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/plgd-dev/go-coap/v2 v2.0.4-0.20200819112225-8eb712b901bc/go.mod h1:+tCi9Q78H/orWRtpVWyBgrr4vKFo2zYtbbxUllerBp4= github.com/plgd-dev/go-coap/v2 v2.4.1-0.20210517130748-95c37ac8e1fa/go.mod h1:rA7fc7ar+B/qa+Q0hRqv7yj/EMtIlmo1l7vkQGSrHPU= @@ -184,35 +176,24 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/traetox/pty v0.0.0-20141209045113-df6c8cd2e0e6 h1:rXBu3Xm94OsXCsv6J4G1QJqP59qpd2AtDXrvF+fnP/o= github.com/traetox/pty v0.0.0-20141209045113-df6c8cd2e0e6/go.mod h1:8GTrdL86wm4Eq6g80gbQjlcmCvDd3uIyIwfpP95gw5g= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/ugorji/go/codec v1.2.8 h1:sgBJS6COt0b/P40VouWKdseidkDgHxYGm0SAglUHfP0= +github.com/ugorji/go/codec v1.2.8/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.12.0/go.mod h1:229t1eWu9UXTPmoUkbpN/fctKPBY4IJoFXQnxHGXy6E= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xiegeo/coloredgoroutine v0.1.1 h1:L6EaQHWIY+oIlKpj5ORu9hIorsLbQwTAStEHSp1SoAs= github.com/xiegeo/coloredgoroutine v0.1.1/go.mod h1:d3jyamWlthEBXOL5qUpKOaaKSJM75HuCIn/z9f4ylrs= github.com/xiegeo/modbusone v1.0.1 h1:owliTRNAg9rP8RM62cMZD+iXu7Kzq4EM1i8zcL3//uY= github.com/xiegeo/modbusone v1.0.1/go.mod h1:Q991qN56vRM6oQftesnNxOVd92fmHvjL0nrYEoAgUs0= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= -github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= -go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= @@ -225,20 +206,19 @@ go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20221106115401-f9659909a136 h1:Fq7F/w7MAa1KJ5bt2aJ62ihqp9HDcRuyILskkpIAurw= -golang.org/x/exp v0.0.0-20221106115401-f9659909a136/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a h1:tlXy25amD5A7gOfbXdqCGN5k8ESEed/Ee1E5RcrYnqU= +golang.org/x/exp v0.0.0-20230108222341-4b8118a2686a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -246,6 +226,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -265,9 +246,10 @@ golang.org/x/net v0.0.0-20210502030024-e5908800b52b/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -275,7 +257,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -298,19 +280,23 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220608164250-635b8c9b7f68/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -324,6 +310,7 @@ golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200417140056-c07e33ef3290/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/configuration/configuration.go b/internal/configuration/configuration.go deleted file mode 100644 index 20700d9..0000000 --- a/internal/configuration/configuration.go +++ /dev/null @@ -1,172 +0,0 @@ -// This package implements the configuration of RiotPot. -// The package contains interfaces that help load, store and modify the configuration. -// NOTE: Not in use -package configuration - -import ( - "embed" - "fmt" - "log" - "os" - "strings" - - arrays "github.com/riotpot/tools/arrays" - environ "github.com/riotpot/tools/environ" - "gopkg.in/yaml.v3" -) - -// Provides common identification attributes for each configuration. -// This structure must be private for each configuration object. -type IdentityConfiguration struct { - ID string - Name string `yaml:"name"` -} - -// RiotPot configuration structure. It includes all the attributes related to the riotpot framework. -// Moreover, it defines the emulators that must be loaded, and watches over them during runtime. -type RiotpotConfiguration struct { - Identity *IdentityConfiguration - // List of emulators that the application can access to. - // This list will be evaluated against the `/pkg/plugin/` dir content. - Emulators []string - // List of plugins used for Riotpot to manage runtime plugins - Start []string -} - -// Database configuration structure. It gives an interface to load and access specific databases. -type DatabaseConfiguration struct { - Identity *IdentityConfiguration - - // username to use in the db - Username string - // password for the user - Password string - // host in where the db is hosted - Host string - // port to connect to the database - Port string - // database name to connect - Name string -} - -// Interface that obligates the child to have the `load` and `save` methods -type ConfigurationProtocol interface { - // Load settings method - Load() - // Save or store settings method - Save() -} - -// General configuration structure. It provides methods and attributes for parsing -// different types of configuration files, store, load and transform the state. -type Configuration struct { - ConfigurationProtocol - - Riotpot RiotpotConfiguration - Database DatabaseConfiguration - - // Private fields - // Configuration file path - configPath string -} - -// Load the configuration on the child. -func (conf *Configuration) Load() (err error) { - // Read the content of the configuration file - var f embed.FS - data, err := f.ReadFile(conf.configPath) - if err != nil { - return - } - - // Serialise the content of the yaml file and load it into the structure - err = yaml.Unmarshal(data, &conf) - if err != nil { - return - } - - return -} - -// Stores the configuration into the given path in `.yml` format. -func (conf *Configuration) Save() (err error) { - // marshal the content of the configuration into a `.yaml` document - d, err := yaml.Marshal(&conf) - if err != nil { - return - } - - // Save to file. - // Mode 640: https://chmodcommand.com/chmod-640/ - // Note: this truncates the file if it already exists !!! - err = os.WriteFile(conf.configPath, d, 0640) - if err != nil { - return - } - - return -} - -// Validates the name of the emulator -func (conf *Configuration) ValidateEmulators(service_paths []string) []string { - var val []string - fmt.Printf("[+] Allowed plugins: %v\n", conf.Riotpot.Emulators) - - for _, p := range service_paths { - // '---path----' ---plugin----- -file- - // split: `*pkg/plugin/` + `/` + `*` - sli := strings.Split(strings.SplitAfter(p, "pkg/plugin/")[1], "/")[0] - // Transform the name of the plugin to lower case - service := strings.ToLower(sli) - - // check if the service is in the allowed emulators slice. - ok := arrays.Contains(conf.Riotpot.Emulators, service) - if ok { - val = append(val, p) - } else { - log.Printf("[-] Plugin %s not allowed, skipping...\n", service) - conf.Riotpot.Start = arrays.DropItem(conf.Riotpot.Start, service) - } - } - // Check if the array of emulators allowed contains the service - return val -} - -// This method overwrites the settings with the values from the environment -func (conf *Configuration) ResolveEnv() { - - // overwrite Starting emulators configuration setting - if value, ok := os.LookupEnv("START"); ok { - if value != "" { - var emulators = strings.Split(value, ",") - conf.Riotpot.Start = emulators - } - } - - // overwrite the default database to be used - var dbCfg = conf.Database - dbCfg = DatabaseConfiguration{ - Username: environ.Getenv("DB_USER", dbCfg.Username), - Password: environ.Getenv("DB_PASS", dbCfg.Password), - Host: environ.Getenv("DB_HOST", dbCfg.Host), - Port: environ.Getenv("DB_PORT", dbCfg.Port), - Name: environ.Getenv("DB_NAME", dbCfg.Name), - } - - dbCfg.Identity.Name = environ.Getenv("DB_NAME", dbCfg.Identity.Name) - - conf.Database = dbCfg -} - -// Constructor for the configuration -// This method loads the configuration from a local file -// then, it overrides the configuration fields with the values from the environment variables -func NewConfiguration() (conf Configuration, err error) { - conf = Configuration{ - configPath: "configs/configuration.yml", - } - - err = conf.Load() - conf.ResolveEnv() - return -} diff --git a/internal/database/database.go b/internal/database/database.go deleted file mode 100644 index 95675f6..0000000 --- a/internal/database/database.go +++ /dev/null @@ -1,83 +0,0 @@ -package database - -import ( - // "fmt" - "context" - "time" - - "github.com/riotpot/internal/configuration" - "github.com/riotpot/tools/errors" - - "go.mongodb.org/mongo-driver/mongo" - "go.mongodb.org/mongo-driver/mongo/options" - "go.mongodb.org/mongo-driver/mongo/readpref" -) - -// Struct that defines the database connection. -// the database connection uses a pool so multiple -// services can push information to the database simultaneously -// through riotpot. -type Database struct { - // Database configuration - conf configuration.DatabaseConfiguration - - // Pointer to the db connection - conn *mongo.Client -} - -// Method to create a connection pool to the database -func (db *Database) connect() (*mongo.Client, error) { - // build the connection url as a string - // dsn := fmt.Sprintf( - // "host=%s user=%s password=%s dbname=%s port=%s sslmode=disable", - // db.Config.Host, - // db.Config.Username, - // db.Config.Password, - // db.Config.Dbname, - // db.Config.Port, - // ) - - // build the credential for the database authentication - credential := options.Credential{ - Username: db.conf.Username, - Password: db.conf.Password, - } - - client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://" + db.conf.Host + ":" + db.conf.Port).SetAuth(credential)) - errors.Raise(err) - - //set the command timeout - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - err = client.Connect(ctx) - - errors.Raise(err) - - // TO-DO: cleanup of the connection may be required in the longer run - // defer client.Disconnect(ctx) - - // test of the database is reachable or not - err = client.Ping(ctx, readpref.Primary()) - errors.Raise(err) - - db.conn = client - - // returns the connection pool as a pointer - return db.conn, err -} - -// Get the connection to the database or create a new one. -func (db *Database) Connection() *mongo.Client { - // check if there is any connection at all - if db.conn != nil { - return db.conn - } else { - conn, err := db.connect() - errors.Raise(err) - return conn - } -} - -func NewDatabase(configuration map[string]string) { - -} diff --git a/internal/database/models.go b/internal/database/models.go deleted file mode 100644 index 8e38c15..0000000 --- a/internal/database/models.go +++ /dev/null @@ -1,30 +0,0 @@ -// This package implements a series of useful model schemas to -// register in the database and use as template to create new -// entries in the database. -package database - -import "time" - -// Schema for a typical connection -type Connection struct { - LocalAddress string - LocalPort string - RemoteAddress string - RemotePort string - // payload sent/received - Payload string - // IP protocol - Protocol string - // the service running on the port - Service string - // wether the connection is from or to the server - Incoming bool - Timestamp time.Time -} - -func NewConnection() Connection { - return Connection{ - // prepare the timestamp - Timestamp: time.Now(), - } -} diff --git a/internal/plugins/keys.go b/internal/plugins/keys.go new file mode 100644 index 0000000..bf0f86b --- /dev/null +++ b/internal/plugins/keys.go @@ -0,0 +1,91 @@ +package plugins + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + + "github.com/riotpot/internal/logger" +) + +type ( + KeyType string + KeySize int +) + +const ( + Public KeyType = "public" + Private KeyType = "private" + + InsecureKey KeySize = 1024 + LiteKey KeySize = 2048 + DefaultKey KeySize = 4096 +) + +type CKey interface { + Generate() []byte + GetPEM() []byte + SetPEM(pem []byte) +} + +type AbstractKey struct { + CKey + pem []byte +} + +func (k *AbstractKey) GetPEM() []byte { + return k.pem +} + +func (k *AbstractKey) SetPEM(pem []byte) { + k.pem = pem +} + +type PrivateKey struct { + key AbstractKey + priv *rsa.PrivateKey +} + +func (k *PrivateKey) GetPEM() []byte { + return k.key.GetPEM() +} + +func (k *PrivateKey) SetPEM(pem []byte) { + k.key.SetPEM(pem) +} + +func (k *PrivateKey) SetKey(key *rsa.PrivateKey) { + k.priv = key +} + +// Function to Generate and store a private RSA key and PEM +func (k *PrivateKey) Generate(size KeySize) (cert []byte) { + reader := rand.Reader + priv, err := rsa.GenerateKey(reader, int(size)) + if err != nil { + logger.Log.Fatal().Err(err) + } + + err = priv.Validate() + if err != nil { + logger.Log.Fatal().Err(err) + } + + block := &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(priv), + } + cert = pem.EncodeToMemory(block) + + k.SetKey(priv) + k.SetPEM(cert) + return +} + +func NewPrivateKey(size KeySize) *PrivateKey { + k := &PrivateKey{} + + k.Generate(size) + return k +} diff --git a/pkg/plugins.go b/internal/plugins/plugins.go similarity index 87% rename from pkg/plugins.go rename to internal/plugins/plugins.go index f2d59c0..4eeb997 100644 --- a/pkg/plugins.go +++ b/internal/plugins/plugins.go @@ -1,14 +1,12 @@ -package pkg +package plugins import ( - "fmt" "path/filepath" "plugin" "github.com/riotpot/internal/logger" - proxies "github.com/riotpot/internal/proxy" + "github.com/riotpot/internal/proxy" "github.com/riotpot/internal/services" - "github.com/riotpot/tools/errors" ) var ( @@ -24,19 +22,19 @@ func getServicePlugin(path string) services.Service { // Open the plugin within the path pg, err := plugin.Open(path) - errors.Raise(err) + logger.Log.Fatal().Err(err) // check the name of the function that exports the service // The plugin *Must* contain a variable called `Plugin`. s, err := pg.Lookup("Plugin") - errors.Raise(err) + logger.Log.Fatal().Err(err) // log the name of the plugin being loaded - fmt.Printf("Loading plugin: %s...\n", *s.(*string)) + logger.Log.Info().Msgf("Loading plugin: %s...\n", *s.(*string)) // check if the reference symbol exists in the plugin rf, err := pg.Lookup(*s.(*string)) - errors.Raise(err) + logger.Log.Error().Err(err) // Load the service in a variable as the interface Service. newservice := rf.(func() services.Service)() @@ -88,13 +86,13 @@ func LoadPlugins() (errors []error) { // Create proxies for each of the started plugins for _, service := range plugins { - proxy, err := proxies.Proxies.CreateProxy(service.GetNetwork(), service.GetPort()-pluginOffset) + px, err := proxy.Proxies.CreateProxy(service.GetNetwork(), service.GetPort()-pluginOffset) if err != nil { logger.Log.Error().Err(err) } // Add the service to the proxy - proxy.SetService(service) + px.SetService(service) } return diff --git a/internal/proxy/tcpproxy.go b/internal/proxy/tcpproxy.go index 2234c43..0d307c8 100644 --- a/internal/proxy/tcpproxy.go +++ b/internal/proxy/tcpproxy.go @@ -52,6 +52,12 @@ func (tcpProxy *TCPProxy) Start() (err error) { } defer client.Close() + // Apply the middlewares to the connection before dialing the server + _, err = tcpProxy.middlewares.Apply(client) + if err != nil { + return + } + // Get a connection to the server for each new connection with the client server, servErr := net.DialTimeout(globals.TCP.String(), tcpProxy.service.GetAddress(), 1*time.Second) @@ -65,9 +71,6 @@ func (tcpProxy *TCPProxy) Start() (err error) { tcpProxy.wg.Add(1) go func() { - // Apply the middlewares to the connection - tcpProxy.middlewares.Apply(client) - // Handle the connection between the client and the server // NOTE: The handlers will defer the connections tcpProxy.handle(client, server) diff --git a/pkg/plugin/coapd/coapd.go b/pkg/plugin/coapd/coapd.go index 6115e15..2fff443 100644 --- a/pkg/plugin/coapd/coapd.go +++ b/pkg/plugin/coapd/coapd.go @@ -19,9 +19,8 @@ import ( "github.com/plgd-dev/go-coap/v2/message/codes" "github.com/plgd-dev/go-coap/v2/mux" "github.com/riotpot/internal/globals" + "github.com/riotpot/internal/logger" "github.com/riotpot/internal/services" - - lr "github.com/riotpot/internal/logger" ) var Plugin string @@ -66,8 +65,6 @@ func (c *Coap) Run() (err error) { // This will cause all the requests to go through this function. r.DefaultHandleFunc(c.observeHandler) - lr.Log.Info().Msgf("Service %s started listenning for connections in port %d", c.GetName(), c.GetPort()) - // Run the server listening on the given port and using the defined // lvl4 layer protocol. err = coap.ListenAndServe(c.GetNetwork().String(), fmt.Sprintf(":%d", c.GetPort()), r) @@ -93,7 +90,7 @@ func (c *Coap) loggingMiddleware(next mux.Handler) mux.Handler { func (c *Coap) observeHandler(w mux.ResponseWriter, req *mux.Message) { path, err := req.Options.Path() if err != nil { - fmt.Print(err) + logger.Log.Error().Err(err) } // divide the path query into //?= @@ -126,7 +123,7 @@ func (c *Coap) observeHandler(w mux.ResponseWriter, req *mux.Message) { // subscription. obs, err := req.Options.Observe() if err != nil { - fmt.Print(err) + logger.Log.Error().Err(err) } topic := c.Profile.GetOrCreateTopic(path, "number") @@ -166,7 +163,7 @@ func (c *Coap) observeHandler(w mux.ResponseWriter, req *mux.Message) { } if err != nil { - lr.Log.Error().Err(err).Msg("Error on transmitter") + logger.Log.Error().Err(err).Msg("Error on transmitter") } } @@ -222,7 +219,7 @@ func (c *Coap) discovery(cc mux.Client, token []byte, path string, flag string, buf = append(buf, make([]byte, n)...) opts, _, err = opts.SetContentFormat(buf, message.AppLinkFormat) if err != nil { - lr.Log.Error().Err(err).Msg("Error on transmitter") + logger.Log.Error().Err(err).Msg("Error on transmitter") } } @@ -265,7 +262,7 @@ func (c *Coap) post(cc mux.Client, token []byte, path string) error { buf = append(buf, make([]byte, n)...) opts, _, err = opts.SetContentFormat(buf, message.AppLinkFormat) if err != nil { - lr.Log.Error().Err(err).Msg("Error on transmitter") + logger.Log.Error().Err(err).Msg("Error on transmitter") } } @@ -350,7 +347,7 @@ func (c *Coap) periodicTransmitter(cc mux.Client, token []byte, topic Topic) { msg := c.msg(topic) err := c.get(cc, token, msg, obs) if err != nil { - lr.Log.Error().Err(err).Msg("Error on transmitter. Shutting down.") + logger.Log.Error().Err(err).Msg("Error on transmitter. Shutting down.") return } diff --git a/pkg/plugin/coapd/profiles.go b/pkg/plugin/coapd/profiles.go index 7288c8b..7b84f81 100644 --- a/pkg/plugin/coapd/profiles.go +++ b/pkg/plugin/coapd/profiles.go @@ -14,7 +14,7 @@ import ( "time" "github.com/google/uuid" - "github.com/riotpot/tools/errors" + "github.com/riotpot/internal/logger" "gopkg.in/yaml.v3" ) @@ -33,9 +33,9 @@ type Profile struct { func (p *Profile) Load(path string) { data, err := os.ReadFile(path) - errors.Raise(err) + logger.Log.Error().Err(err) err = yaml.Unmarshal(data, &p) - errors.Raise(err) + logger.Log.Error().Err(err) } // Method that provides a getter for topics and anso creates the topic diff --git a/pkg/plugin/echod/echod.go b/pkg/plugin/echod/echod.go index 7c6ce5d..f751246 100644 --- a/pkg/plugin/echod/echod.go +++ b/pkg/plugin/echod/echod.go @@ -6,8 +6,8 @@ import ( "net" "github.com/riotpot/internal/globals" + "github.com/riotpot/internal/logger" "github.com/riotpot/internal/services" - "github.com/riotpot/tools/errors" ) var Plugin string @@ -41,7 +41,7 @@ func (e *Echo) Run() (err error) { // start a service in the `echo` port listener, err := net.Listen(e.GetNetwork().String(), port) - errors.Raise(err) + logger.Log.Error().Err(err) // build a channel stack to receive connections to the service conn := make(chan net.Conn) @@ -50,9 +50,6 @@ func (e *Echo) Run() (err error) { // handle the connections from the channel e.handlePool(conn) - // Close the channel for stopping the service - fmt.Print("[x] Service stopped...\n") - return } @@ -60,7 +57,6 @@ func (e *Echo) Run() (err error) { // inspired on https://gist.github.com/paulsmith/775764#file-echo-go func (e *Echo) serve(ch chan net.Conn, listener net.Listener) { // open an infinite loop to receive connections - fmt.Printf("[%s] Started listenning for connections in port %d\n", e.GetName(), e.GetPort()) for { // Accept the client connection client, err := listener.Accept() diff --git a/pkg/plugin/httpd/httpd.go b/pkg/plugin/httpd/httpd.go index e106460..f21b385 100644 --- a/pkg/plugin/httpd/httpd.go +++ b/pkg/plugin/httpd/httpd.go @@ -14,7 +14,7 @@ var Plugin string const ( name = "HTTP" network = globals.TCP - port = 8080 + port = 80 ) func init() { @@ -49,7 +49,6 @@ func (h *Http) Run() (err error) { } func (h *Http) serve(srv *http.Server) { - fmt.Printf("[%s] Started listenning for connections in port %d\n", h.GetName(), h.GetPort()) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { lr.Log.Fatal().Err(err) } diff --git a/pkg/plugin/modbusd/modbusd.go b/pkg/plugin/modbusd/modbusd.go index c1bd856..4971630 100644 --- a/pkg/plugin/modbusd/modbusd.go +++ b/pkg/plugin/modbusd/modbusd.go @@ -6,8 +6,8 @@ import ( "net" "github.com/riotpot/internal/globals" + "github.com/riotpot/internal/logger" "github.com/riotpot/internal/services" - "github.com/riotpot/tools/errors" "github.com/xiegeo/modbusone" ) @@ -54,7 +54,7 @@ func (m *Modbus) Run() (err error) { // start a service in the `echo` port listener, err := net.Listen("tcp", port) - errors.Raise(err) + logger.Log.Error().Err(err) // build a channel stack to receive connections to the service conn := make(chan net.Conn) @@ -67,7 +67,6 @@ func (m *Modbus) Run() (err error) { // inspired on https://gist.github.com/paulsmith/775764#file-echo-go func (m *Modbus) serve(ch chan net.Conn, listener net.Listener) { // open an infinite loop to receive connections - fmt.Printf("[%s] Started listenning for connections in port %d\n", m.GetName(), m.GetPort()) for { // Accept the client connection client, err := listener.Accept() @@ -216,7 +215,7 @@ func handler() modbusone.ProtocolHandler { // It might be that an "slave" wants to report an error // we want to gather that information as well. OnErrorImp: func(req modbusone.PDU, errRep modbusone.PDU) { - fmt.Printf("error received: %v from req: %v\n", errRep, req) + logger.Log.Error().Msgf("error received: %v from req: %v\n", errRep, req) }, } } diff --git a/pkg/plugin/mqttd/fixedheaders.go b/pkg/plugin/mqttd/fixedheaders.go index 436a14a..3655d11 100644 --- a/pkg/plugin/mqttd/fixedheaders.go +++ b/pkg/plugin/mqttd/fixedheaders.go @@ -5,6 +5,7 @@ import ( "io" "net" + "github.com/riotpot/internal/logger" "github.com/riotpot/tools/arrays" ) @@ -14,7 +15,7 @@ func NewFixedHeader(conn *net.Conn) *FixedHeader { n, _ := io.ReadFull(*conn, b) if n != len(b) { - fmt.Print("read header failed\n") + logger.Log.Error().Msg("read header failed\n") return nil } diff --git a/pkg/plugin/mqttd/mqttd.go b/pkg/plugin/mqttd/mqttd.go index 01a4304..b0ff693 100644 --- a/pkg/plugin/mqttd/mqttd.go +++ b/pkg/plugin/mqttd/mqttd.go @@ -7,8 +7,8 @@ import ( "sync" "github.com/riotpot/internal/globals" + "github.com/riotpot/internal/logger" "github.com/riotpot/internal/services" - "github.com/riotpot/tools/errors" ) var Plugin string @@ -44,7 +44,7 @@ func (m *Mqtt) Run() (err error) { // start a service in the `mqtt` port listener, err := net.Listen(m.GetNetwork().String(), port) - errors.Raise(err) + logger.Log.Error().Err(err) // build a channel stack to receive connections to the service conn := make(chan net.Conn) @@ -66,7 +66,6 @@ func (m *Mqtt) serve(ch chan net.Conn, listener net.Listener) { defer m.wg.Done() // open an infinite loop to receive connections - fmt.Printf("[%s] Started listenning for connections in port %d\n", m.GetName(), m.GetPort()) for { // Accept the client connection client, err := listener.Accept() diff --git a/pkg/plugin/mqttd/sessions.go b/pkg/plugin/mqttd/sessions.go index 4f57fd3..475329b 100644 --- a/pkg/plugin/mqttd/sessions.go +++ b/pkg/plugin/mqttd/sessions.go @@ -11,9 +11,10 @@ package main import ( "bytes" - "fmt" "io" "net" + + "github.com/riotpot/internal/logger" ) func NewSession(conn net.Conn) *Session { @@ -84,7 +85,7 @@ func (s *Session) Answer(p Packet, conn *net.Conn) { // copy the fixed header from the packet msg, err := p.EncodeAnswer() if err != nil { - fmt.Printf("[!] Error: %v\n", err) + logger.Log.Error().Err(err) return } diff --git a/pkg/plugin/sshd/sshd.go b/pkg/plugin/sshd/sshd.go index 1479b60..9d0a355 100644 --- a/pkg/plugin/sshd/sshd.go +++ b/pkg/plugin/sshd/sshd.go @@ -3,14 +3,15 @@ package main import ( "fmt" "io" - "io/ioutil" "net" "sync" "github.com/riotpot/internal/globals" + "github.com/riotpot/internal/logger" + "github.com/riotpot/internal/plugins" "github.com/riotpot/internal/services" "github.com/riotpot/pkg/fake/shell" - "github.com/riotpot/tools/errors" + "github.com/traetox/pty" "golang.org/x/crypto/ssh" ) @@ -31,13 +32,13 @@ func init() { func Sshd() services.Service { mx := services.NewPluginService(name, port, network) - pKey, err := ioutil.ReadFile("riopot_rsa") - errors.Raise(err) + pKey := plugins.NewPrivateKey(plugins.DefaultKey) + pem := pKey.GetPEM() return &SSH{ Service: mx, wg: sync.WaitGroup{}, - privateKey: pKey, + privateKey: pem, } } @@ -49,20 +50,22 @@ type SSH struct { func (s *SSH) Run() (err error) { - // Pre load the configuration for the ssh server + // Preload the configuration for the ssh server config := &ssh.ServerConfig{ PasswordCallback: s.auth, } // Add a private key for the connections - config.AddHostKey(s.PrivateKey()) + priv := s.PrivateKey() + config.AddHostKey(priv) // convert the port number to a string that we can use it in the server - var port = fmt.Sprintf(":%d", s.GetPort()) + port := fmt.Sprintf(":%d", s.GetPort()) - // start a service in the `echo` port listener, err := net.Listen(s.GetNetwork().String(), port) - errors.Raise(err) + if err != nil { + return + } defer listener.Close() // build a channel stack to receive connections to the service @@ -85,43 +88,33 @@ func (s *SSH) auth(c ssh.ConnMetadata, pass []byte) (perms *ssh.Permissions, err func (s *SSH) serve(listener net.Listener, config *ssh.ServerConfig) { // open an infinite loop to receive connections - fmt.Printf("[%s] Started listenning for connections in port %d\n", s.GetName(), s.GetPort()) for { // Accept the client connection client, err := listener.Accept() if err != nil { - return + logger.Log.Error().Err(err) + continue } - defer client.Close() // upgrade the connections to ssh sshConn, chans, reqs, err := ssh.NewServerConn(client, config) if err != nil { - fmt.Printf("Failed to handshake (%s)", err) + logger.Log.Error().Err(err) continue } sshItem := NewSshConn(sshConn) - defer sshConn.Close() - defer sshConn.Conn.Close() - s.wg.Add(1) // Discard all global out-of-band Requests go ssh.DiscardRequests(reqs) // Handle all the channels open by the connection - s.handleChannels(sshItem, chans) - s.wg.Wait() + go s.handleChannels(sshItem, chans) } } func (s *SSH) handleChannels(sshItem SSHConn, chans <-chan ssh.NewChannel) { for conn := range chans { - //TODO: this line crashes the app when the connection is lost!!! - // NOTE: As of [6/21/2022] this line has not been fixed yet. - // Fix it ASAP! - // ☟ ☟ ☟ go s.handleChannel(sshItem, conn) - // ☝ ☝ ☝ } } @@ -136,7 +129,7 @@ func (s *SSH) handleChannel(sshItem SSHConn, channel ssh.NewChannel) { // Accept the channel creation request conn, requests, err := channel.Accept() if err != nil { - fmt.Printf("Could not accept channel (%s)", err) + logger.Log.Error().Err(err) return } @@ -146,23 +139,23 @@ func (s *SSH) handleChannel(sshItem SSHConn, channel ssh.NewChannel) { } // Out-of-band requests handler -// inspired in: https://github.com/traetox/sshForShits/ func (s *SSH) oob(sshItem SSHConn, requests <-chan *ssh.Request, conn ssh.Channel) { + for req := range requests { + switch req.Type { case "shell": - if len(req.Payload) == 0 { - req.Reply(true, nil) - } else { - req.Reply(false, nil) + if len(req.Payload) > 0 { + logger.Log.Error().Msgf("Shell command ignored", req.Payload) } // Give a shell to the client err := s.attachShell(sshItem, conn) if err != nil { - return + logger.Log.Error().Err(err) } + req.Reply(err == nil, nil) case "pty-req": // Responding 'ok' here will let the client // know we have a pty ready for input @@ -172,7 +165,7 @@ func (s *SSH) oob(sshItem SSHConn, requests <-chan *ssh.Request, conn ssh.Channe case "env": continue // no response default: - fmt.Printf("unkown request: %s (reply: %v, data: %x)", req.Type, req.WantReply, req.Payload) + logger.Log.Info().Msgf("Unkown request: %s (reply: %v, data: %x)", req.Type, req.WantReply, req.Payload) } } } @@ -210,7 +203,9 @@ func (s *SSH) attachShell(sshItem SSHConn, conn ssh.Channel) (err error) { func (s *SSH) PrivateKey() (key ssh.Signer) { // Gets the signer from a key key, err := ssh.ParsePrivateKey(s.privateKey) - errors.Raise(err) + if err != nil { + logger.Log.Fatal().Err(err) + } return } diff --git a/pkg/plugin/telnetd/telnetd.go b/pkg/plugin/telnetd/telnetd.go index cc370c9..407d1bd 100644 --- a/pkg/plugin/telnetd/telnetd.go +++ b/pkg/plugin/telnetd/telnetd.go @@ -7,10 +7,10 @@ import ( "net" "github.com/riotpot/internal/globals" + "github.com/riotpot/internal/logger" lr "github.com/riotpot/internal/logger" "github.com/riotpot/internal/services" "github.com/riotpot/pkg/fake/shell" - "github.com/riotpot/tools/errors" ) var Plugin string @@ -50,7 +50,7 @@ func (t *Telnet) Run() (err error) { // start a service in the `telnet` port listener, err := net.Listen(t.GetNetwork().String(), port) - errors.Raise(err) + logger.Log.Error().Err(err) // build a channel stack to receive connections to the service conn := make(chan net.Conn) @@ -64,7 +64,6 @@ func (t *Telnet) Run() (err error) { func (t *Telnet) serve(ch chan net.Conn, listener net.Listener) { // open an infinite loop to receive connections - fmt.Printf("[%s] Started listenning for connections in port %d\n", t.GetName(), t.GetPort()) for { // Accept the client connection client, err := listener.Accept() diff --git a/test/internal/configuration/configuration_test.go b/test/internal/configuration/configuration_test.go deleted file mode 100644 index f13760f..0000000 --- a/test/internal/configuration/configuration_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package configuration - -import ( - "encoding/json" - "os" - "testing" - - cfg "github.com/riotpot/internal/configuration" -) - -var ( - settings = cfg.Configuration{} - path = "./configuration_test.yml" -) - -// Test loading and saving configuration from a file to another -// TODO: Since the test is broken the real function has not been tested. Change this. -func TestLoadAndSaveConf(t *testing.T) { - // load the configuration - err := settings.Load() - if err != nil { - t.Error(err) - } - - // pretty print marshalling to json - out, err := json.MarshalIndent(settings, "", " ") - if err != nil { - t.Error(err) - } - - t.Logf("%s\n", string(out)) - - // save the configuration - err = settings.Save() - if err != nil { - t.Error(err) - } - - // read the file just saved and prints it - data, err := os.ReadFile(path) - if err != nil { - t.Error(err) - } - - t.Log(string(data)) - -} diff --git a/test/internal/configuration/configuration_test.yml b/test/internal/configuration/configuration_test.yml deleted file mode 100644 index 7333894..0000000 --- a/test/internal/configuration/configuration_test.yml +++ /dev/null @@ -1,57 +0,0 @@ ---- -version: 1 -type: template -# RiotPot configuration file. -# This file can be used as a template for further implementations and as a record of -# documentation for internal structure when in doubt on usage. - -# 50 characters minimum long RANDOM string used to generate cryptographic signatures. -secret: - -riotpot: - # If this boolean is set to a falsy value then `start` must be filled with the - # list of services desired to be loaded and run at start, and `emulators` with - # the list of available services to the app. - autod: false - - # The name of the services is the name of the folder in which the plugin - # is stored, inside the `pkg/` folder. - # Example: - # * if the plugin is stored in: `pkg/telnetd` - # * then place: `- telnetd` - - # `start` contains a list of services desired to be run - # on-start. For all the services, set `autod` to `true`. - start: - - httpd - - # Contains a list of available services in the application. - # This gives the user the ability to navigate or load - # just the emulators that appear in this list, wether or not - # the emulator plugin appears in the binary. - # - # Add here the emulator plugins you have included on the binary. - emulators: - - httpd - - echod - - sshd - - telnetd - -# The `databases` object contains a number of object defined database -# connection information. As the name indicates, `default` will be the default -# database used to store logs, binary entries, etc. -databases: - - identity: - # Name of the targeted database - name: default - # RiotPot only supports `postgres` currently. - engine: postgres - # IP or container name in the same network. - host: localhost - # Connection port to the database host. - port: 5432 - # User and password to access the database. - # NOTE: Do not hard-code the values in this file. Please do make - # use of `.env` file for this purpose in production. - username: superuser - password: diff --git a/test/pkg/plugins_test.go b/test/internal/plugins/plugins_test.go similarity index 56% rename from test/pkg/plugins_test.go rename to test/internal/plugins/plugins_test.go index 02a2b7d..7021766 100644 --- a/test/pkg/plugins_test.go +++ b/test/internal/plugins/plugins_test.go @@ -4,27 +4,34 @@ import ( "testing" lr "github.com/riotpot/internal/logger" + "github.com/riotpot/internal/plugins" "github.com/riotpot/internal/services" - "github.com/riotpot/pkg" "github.com/stretchr/testify/assert" ) var ( - pluginPath = "../../bin/plugins/*.so" + pluginPath = "../../../bin/plugins/*.so" ) func TestLoadPlugins(t *testing.T) { - plugins, err := pkg.GetPluginServices(pluginPath) + pgs, err := plugins.GetPluginServices(pluginPath) if err != nil { lr.Log.Fatal().Err(err).Msgf("One or more services could not be found") } - plg := plugins[0] + assert.Equal(t, 1, len(pgs)) + + plg := pgs[0] i, ok := plg.(services.PluginService) if !ok { lr.Log.Fatal().Err(err).Msgf("Service is not a plugin") } go i.Run() +} + +func TestNewPrivateKey(t *testing.T) { + key := plugins.NewPrivateKey(plugins.DefaultKey) + pem := key.GetPEM() - assert.Equal(t, 1, len(plugins)) + assert.Equal(t, 1, len(pem)) } diff --git a/tools/arrays/array.go b/tools/arrays/array.go index 8bf19f8..70e601a 100644 --- a/tools/arrays/array.go +++ b/tools/arrays/array.go @@ -5,8 +5,7 @@ import ( "strings" ) -// TODO: Add comments to the functions. It is impossible to eyeball what does everything do - +// Function to check whether an array of strings contains a string value func Contains(in []string, str string) bool { for _, v := range in { if !strings.EqualFold(strings.ToLower(v), strings.ToLower(str)) { @@ -16,52 +15,3 @@ func Contains(in []string, str string) bool { return true } - -// TODO: This function does not do what it advertises, it iterates through an array -// and do not add a single value lol -func DropItem(in []string, item string) (out_array []string) { - for _, val := range in { - if item != val { - out_array = append(out_array, val) - } - } - return out_array -} - -func StringToArray(in string) []string { - return strings.Fields(in) -} - -// TODO: Rename to index or something standard. -func GetItemPosition(in_array []string, item string) int { - for pos, val := range in_array { - if val == item { - return pos - } - } - return -1 -} - -// TODO: Remove this function -func AddSuffix(in string, suffix string) string { - return (in + suffix) -} - -// TODO: This function does not do what it advertises! -// The function returns something midway, and then assigns something else -// Check the behaviour of this function at somepoint -func HaveDuplicateItems(array []string) bool { - array_map := make(map[string]bool) - - for _, item := range array { - if array_map[item] { - return true - } - array_map[item] = true - } - return false -} - -func ArrayToString(array []string) string { - return strings.Join(array, " ") -} diff --git a/tools/environ/syscmd.go b/tools/environ/syscmd.go deleted file mode 100644 index d96da07..0000000 --- a/tools/environ/syscmd.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Package environ provides functions used to interact with the environment -*/ -package environ - -import ( - "log" - "os/exec" - "github.com/riotpot/tools/arrays" -) - -// get the full binary path on host for a given service -func GetPath(service string) (servicePath string) { - servicePath, err := exec.LookPath(service) - - if err != nil { - log.Fatalf("Error in getting service %q with error %q \n", service, err ) - } - return servicePath -} - -// Execute terminal command in async mode i.e. in background -func ExecuteBackgroundCmd(app string, args ...string) { - cmd := exec.Command(app, args...) - err := cmd.Start() - - if err != nil { - log.Fatalf("cmd.Run() for command %q %q failed with %s\n", app, args, err) - } -} - -// Execute command and return the output, if any -func ExecuteCmd(app string, args ...string) (output string) { - cmd := exec.Command(app, args...) - out, err := cmd.CombinedOutput() - - if err != nil { - log.Fatalf("cmd.Run() for command %q %q failed with %s\n", app, args, err) - } - - return string(out) -} - -// Outputs if docker container of the given name exists already -func CheckDockerExists(name string) (bool) { - arg := "name="+name - cmd := ExecuteCmd("docker", "ps", "-a", "--filter", arg) - // Convert the command output to array and check if name exists - return arrays.Contains(arrays.StringToArray(cmd), name) -} diff --git a/tools/errors/errors.go b/tools/errors/errors.go deleted file mode 100644 index bb412de..0000000 --- a/tools/errors/errors.go +++ /dev/null @@ -1,23 +0,0 @@ -// This package implements multiple errors specific to riotpot -package errors - -import ( - "fmt" - "log" -) - -const ( - EmulatorNotInstalled = "Emulator not installed." -) - -func Error(name string, errorString string) { - err := fmt.Errorf("[!] Error: %s\n > %s", name, errorString) - fmt.Println(err) -} - -// Check if there is an error and throw a fatal -func Raise(err error) { - if err != nil { - log.Fatalf("[!] Error: %v", err) - } -}