├── suryansh_d
├── test
├── code
│ └── cis-benchmark-audit-tool
│ │ ├── logo1.png
│ │ ├── .go.mod.swp
│ │ ├── assets
│ │ └── logo.png
│ │ ├── internal
│ │ ├── gui
│ │ │ ├── .gui.go.swn
│ │ │ ├── .gui.go.swo
│ │ │ ├── .gui.go.swp
│ │ │ └── gui.go
│ │ ├── benchmarks
│ │ │ ├── .linux.go.swp
│ │ │ ├── windows.go
│ │ │ └── linux.go
│ │ ├── config
│ │ │ └── config.go
│ │ └── report
│ │ │ └── report.go
│ │ ├── cmd
│ │ └── linux
│ │ │ └── main.go
│ │ ├── install_dependencies.go
│ │ ├── go.mod
│ │ ├── audit_report.html
│ │ └── go.sum
├── bachahua_hua_kaam.txt
├── test_fyne
│ └── 1.go
├── objective
├── python_vs_go
└── flow.txt
├── go_install.py
└── README.md
/suryansh_d/test:
--------------------------------------------------------------------------------
1 | l vlkjfv
2 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethical-buddy/SIH24/HEAD/suryansh_d/code/cis-benchmark-audit-tool/logo1.png
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/.go.mod.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethical-buddy/SIH24/HEAD/suryansh_d/code/cis-benchmark-audit-tool/.go.mod.swp
--------------------------------------------------------------------------------
/suryansh_d/bachahua_hua_kaam.txt:
--------------------------------------------------------------------------------
1 | ppt bnani hai
2 | benchmarks lagane hai
3 | main.go bahar chahia
4 | windows.go ko call na kre
5 | report file me output in pdf
6 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethical-buddy/SIH24/HEAD/suryansh_d/code/cis-benchmark-audit-tool/assets/logo.png
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/gui/.gui.go.swn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethical-buddy/SIH24/HEAD/suryansh_d/code/cis-benchmark-audit-tool/internal/gui/.gui.go.swn
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/gui/.gui.go.swo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethical-buddy/SIH24/HEAD/suryansh_d/code/cis-benchmark-audit-tool/internal/gui/.gui.go.swo
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/gui/.gui.go.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethical-buddy/SIH24/HEAD/suryansh_d/code/cis-benchmark-audit-tool/internal/gui/.gui.go.swp
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/benchmarks/.linux.go.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ethical-buddy/SIH24/HEAD/suryansh_d/code/cis-benchmark-audit-tool/internal/benchmarks/.linux.go.swp
--------------------------------------------------------------------------------
/suryansh_d/test_fyne/1.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fyne.io/fyne/v2"
5 | "fyne.io/fyne/v2/app"
6 | "fyne.io/fyne/v2/widget"
7 | )
8 |
9 | func main() {
10 | a := app.New()
11 | w := a.NewWindow("Hello World")
12 |
13 | w.SetContent(widget.NewLabel("Hello World!"))
14 | w.Show()
15 |
16 | w2 := a.NewWindow("Larger")
17 | w2.SetContent(widget.NewLabel("More content"))
18 | w2.Resize(fyne.NewSize(100, 100))
19 | w2.Show()
20 |
21 | a.Run()
22 | }
23 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/config/config.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "encoding/json"
5 | "os"
6 | )
7 |
8 | type Config struct {
9 | WindowsChecks []string `json:"windows_checks"`
10 | LinuxChecks []string `json:"linux_checks"`
11 | }
12 |
13 | func LoadConfig(filename string) (*Config, error) {
14 | file, err := os.Open(filename)
15 | if err != nil {
16 | return nil, err
17 | }
18 | defer file.Close()
19 |
20 | var config Config
21 | decoder := json.NewDecoder(file)
22 | err = decoder.Decode(&config)
23 | if err != nil {
24 | return nil, err
25 | }
26 | return &config, nil
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/report/report.go:
--------------------------------------------------------------------------------
1 | package report
2 |
3 | import (
4 | "os"
5 | "fmt"
6 | )
7 |
8 | type Report struct {
9 | Results []string
10 | }
11 |
12 | func (r *Report) AddResult(result string) {
13 | r.Results = append(r.Results, result)
14 | }
15 |
16 | func (r *Report) GenerateReport(filename string) error {
17 | file, err := os.Create(filename)
18 | if err != nil {
19 | return err
20 | }
21 | defer file.Close()
22 |
23 | for _, result := range r.Results {
24 | _, err := file.WriteString(result + "\n")
25 | if err != nil {
26 | return err
27 | }
28 | }
29 | fmt.Println("Report generated:", filename)
30 | return nil
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/cmd/linux/main.go:
--------------------------------------------------------------------------------
1 | /*package main
2 |
3 | import (
4 | "cis-benchmark-audit-tool/internal/benchmarks"
5 | "cis-benchmark-audit-tool/internal/gui"
6 | "fmt"
7 | "cis-benchmark-audit-tool/internal/report"
8 |
9 | )
10 |
11 | func main() {
12 |
13 | go benchmarks.RunLinuxChecks()
14 | gui.CreateGUI()
15 | {
16 | r := report.Report{}
17 | r.AddResult("Check 1: Passed")
18 | r.AddResult("Check 2: Failed")
19 | r.AddResult("Check 3: Passed")
20 |
21 | err := r.GenerateReport("audit_report.txt")
22 | if err != nil {
23 | fmt.Println("Error generating report:", err)}
24 | }
25 | }*/
26 |
27 | package main
28 |
29 | import (
30 | "cis-benchmark-audit-tool/internal/gui"
31 | )
32 |
33 | func main() {
34 | // Initialize and start the GUI
35 | gui.CreateGUI()
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/install_dependencies.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os/exec"
6 | )
7 |
8 | func installPackages(packages []string) {
9 | for _, pkg := range packages {
10 | cmd := exec.Command("sudo", "apt-get", "install", "-y", pkg)
11 | err := cmd.Run()
12 | if err != nil {
13 | log.Fatalf("Failed to install package %s: %v", pkg, err)
14 | }
15 | log.Printf("Successfully installed package: %s", pkg)
16 | }
17 | }
18 |
19 | func main() {
20 | // List of packages required for the benchmarks
21 | packages := []string{
22 | "iptables", // For firewall checks
23 | "e2fsprogs", // For filesystems checks
24 | "lvm2", // For partition checks
25 | "usbutils", // For USB storage checks
26 | "automount", // For automounting checks
27 | "dosfstools", // For filesystem checks
28 | "bsdmainutils", // For additional system utilities
29 | "systemd-sysv", // For systemd and service management
30 | }
31 |
32 | installPackages(packages)
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/suryansh_d/objective:
--------------------------------------------------------------------------------
1 | Problem Explanation
2 | Problem Statement:
3 | Organizations across various industries struggle to maintain a strong cybersecurity posture. One of the key ways to ensure this is by complying with industry standards like the Center for Internet Security (CIS) benchmarks. These benchmarks provide specific guidelines for securing IT infrastructures. However, manually auditing systems to ensure compliance with these guidelines is time-consuming, prone to errors, and resource-intensive. Therefore, there is a need for automated auditing scripts that can check compliance with CIS benchmarks for different operating systems like Windows 11 and Linux distributions.
4 |
5 | Objective:
6 | The goal is to develop a software solution that automates the process of auditing systems against CIS benchmarks for Windows 11 and various Linux distributions. The solution should:
7 |
8 | Be user-friendly and GUI-based.
9 | Generate reports of findings.
10 | Be customizable for different organizational needs.
11 | Accurately identify deviations from CIS benchmarks.
12 | Be easy to update as benchmarks evolve.
13 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/go.mod:
--------------------------------------------------------------------------------
1 | module cis-benchmark-audit-tool
2 |
3 | go 1.22.6
4 |
5 | require (
6 | fyne.io/fyne/v2 v2.5.1
7 | github.com/jung-kurt/gofpdf v1.16.2
8 | )
9 |
10 | require (
11 | fyne.io/systray v1.11.0 // indirect
12 | github.com/BurntSushi/toml v1.4.0 // indirect
13 | github.com/davecgh/go-spew v1.1.1 // indirect
14 | github.com/fredbi/uri v1.1.0 // indirect
15 | github.com/fsnotify/fsnotify v1.7.0 // indirect
16 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect
17 | github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirect
18 | github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect
19 | github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
20 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirect
21 | github.com/go-text/render v0.1.1-0.20240418202334-dd62631dae9b // indirect
22 | github.com/go-text/typesetting v0.1.0 // indirect
23 | github.com/godbus/dbus/v5 v5.1.0 // indirect
24 | github.com/gopherjs/gopherjs v1.17.2 // indirect
25 | github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 // indirect
26 | github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
27 | github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
28 | github.com/pmezard/go-difflib v1.0.0 // indirect
29 | github.com/rymdport/portal v0.2.6 // indirect
30 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
31 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
32 | github.com/stretchr/testify v1.8.4 // indirect
33 | github.com/yuin/goldmark v1.7.1 // indirect
34 | golang.org/x/image v0.18.0 // indirect
35 | golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect
36 | golang.org/x/net v0.25.0 // indirect
37 | golang.org/x/sys v0.20.0 // indirect
38 | golang.org/x/text v0.16.0 // indirect
39 | gopkg.in/yaml.v3 v3.0.1 // indirect
40 | )
41 |
--------------------------------------------------------------------------------
/go_install.py:
--------------------------------------------------------------------------------
1 | import platform
2 | import subprocess
3 | import sys
4 | import os
5 |
6 | def run_command(command, shell=True):
7 | result = subprocess.run(command, shell=shell, text=True, capture_output=True)
8 | print(result.stdout)
9 | if result.returncode != 0:
10 | print(f"Error occurred while running command: {result.stderr}", file=sys.stderr)
11 | sys.exit(result.returncode)
12 |
13 | platform_name = platform.system()
14 |
15 | if platform_name == "Linux":
16 | go_tarball_url = "https://go.dev/dl/go1.23.0.linux-amd64.tar.gz"
17 | go_tarball = "go1.23.0.linux-amd64.tar.gz"
18 | run_command("sudo rm -rf /usr/local/go")
19 | run_command(f"wget {go_tarball_url} -O {go_tarball}")
20 | run_command(f"sudo tar -C /usr/local -xf {go_tarball}")
21 | run_command("echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile", shell=True)
22 | run_command("echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc", shell=True)
23 | run_command("echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.zshrc", shell=True)
24 | run_command("source ~/.profile", shell=True)
25 | run_command("source ~/.bashrc", shell=True)
26 | run_command("source ~/.zshrc", shell=True)
27 | run_command("go version")
28 |
29 | print("Go installed successfully on Linux.")
30 |
31 | elif platform_name == "Windows":
32 | go_installer_url = "https://go.dev/dl/go1.23.0.windows-amd64.msi"
33 | go_installer = "go1.23.0.windows-amd64.msi"
34 |
35 | run_command(f"wget {go_installer_url} -O {go_installer}")
36 | run_command(f"msiexec /i {go_installer} /quiet /norestart")
37 | go_path = r"C:\Go\bin"
38 | run_command(f"setx PATH \"%PATH%;{go_path}\"", shell=True)
39 | run_command("go version")
40 |
41 | print("Go installed successfully on Windows.")
42 |
43 | elif platform_name == "Darwin": # "Darwin" is the platform name for macOS
44 | go_tarball_url = "https://golang.org/dl/go1.23.0.darwin-amd64.tar.gz"
45 | go_tarball = "go1.23.0.darwin-amd64.tar.gz"
46 | run_command("sudo rm -rf /usr/local/go")
47 | run_command(f"wget {go_tarball_url} -O {go_tarball}")
48 |
49 | run_command(f"sudo tar -C /usr/local -xf {go_tarball}")
50 | run_command("echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.zshrc", shell=True)
51 | run_command("source ~/.zshrc", shell=True)
52 |
53 | run_command("go version")
54 | print("Go installed successfully on macOS.")
55 |
56 | else:
57 | print("Unsupported platform.")
58 | sys.exit(1)
59 |
60 | # Change to the directory containing this script
61 | script_dir = os.path.dirname(os.path.abspath(__file__))
62 | os.chdir(script_dir)
63 |
64 | # Execute the main.go file if it exists
65 | if os.path.isfile("main.go"):
66 | run_command("go run main.go")
67 | else:
68 | print("main.go file not found.")
69 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/audit_report.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | CIS Benchmark Audit Report
8 |
29 |
30 |
31 |
32 |
35 |
36 | Disable Cramfs passed: cramfs module disabled successfully.
37 | Ensure noexec option on /var/log/audit failed: noexec option is not set on /var/log/audit partition
38 | Disable Squashfs passed: squashfs module disabled successfully.
39 | Ensure noexec option on /tmp failed: noexec option is not set on /tmp partition
40 | Ensure nosuid option on /tmp passed: nosuid option is set on /tmp partition.
41 | Ensure /var/log/audit is a Separate Partition failed: /var/log/audit is not a separate partition
42 | Ensure nosuid option on /dev/shm passed: nosuid option is set on /dev/shm partition.
43 | Ensure USB Storage is Disabled passed: USB storage disabled successfully.
44 | Disable Freevxfs passed: freevxfs module disabled successfully.
45 | Disable Jffs2 passed: jffs2 module disabled successfully.
46 | Ensure noexec option on /dev/shm failed: noexec option is not set on /dev/shm partition
47 | Check Linux Firewall passed: Status: active
48 |
49 | Ensure nosuid option on /home failed: nosuid option is not set on /home partition
50 | Disable Hfs passed: hfs module disabled successfully.
51 | Ensure nosuid option on /var failed: nosuid option is not set on /var partition
52 | Ensure automounting is Disabled failed: Failed to check automounting status: exit status 4
53 | Ensure /var/log is a Separate Partition failed: /var/log is not a separate partition
54 | Ensure nosuid option on /var/log/audit failed: nosuid option is not set on /var/log/audit partition
55 | Ensure /var is a Separate Partition failed: /var is not a separate partition
56 | Ensure nodev option on /var failed: nodev option is not set on /var partition
57 | Ensure /var/tmp is a Separate Partition failed: /var/tmp is not a separate partition
58 | Ensure nodev option on /var/tmp failed: nodev option is not set on /var/tmp partition
59 | Ensure nosuid option on /var/log failed: nosuid option is not set on /var/log partition
60 | Ensure nodev option on /home failed: nodev option is not set on /home partition
61 | Disable Udf passed: udf module disabled successfully.
62 | Ensure /tmp is a Separate Partition failed: /tmp is not a separate partition
63 | Ensure nodev option on /dev/shm passed: nodev option is set on /dev/shm partition.
64 | Ensure nodev option on /tmp passed: nodev option is set on /tmp partition.
65 | Ensure noexec option on /var/log failed: noexec option is not set on /var/log partition
66 |
67 |
68 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Automated CIS Benchmark Auditing Tool For Linux And Windows
2 |
3 | ## Overview
4 |
5 | Maintaining a robust cybersecurity posture is crucial for organizations across various industries. Compliance with industry standards and guidelines, such as those provided by the Center for Internet Security (CIS), is essential for ensuring the security and integrity of IT infrastructure. Manually auditing and ensuring adherence to these benchmarks is time-consuming, error-prone, and resource-intensive. This project aims to address these challenges by providing automated auditing scripts tailored to CIS benchmarks for different operating systems.
6 |
7 | ## Description
8 |
9 | This software solution provides automated auditing capabilities for CIS benchmarks across various operating systems. The tool lists control guidelines as per CIS benchmarks for the following operating systems:
10 |
11 | - **Windows**
12 | - Windows 11 (Enterprise version)
13 | - Windows 11 (Standalone version)
14 | - **Linux**
15 | - Red Hat Enterprise Linux (8 and 9)
16 | - Ubuntu Desktop (20.04 LTS, 22.04 LTS)
17 | - Ubuntu Server (12.04 LTS and 14.04 LTS)
18 |
19 | ## Features
20 |
21 | - **Fast**: Utilizes Go concurrency to achieve faster and more efficient audits.
22 | - **Automated Auditing**: Efficiently automate the process of auditing system configurations against CIS benchmarks.
23 | - **User-Friendly GUI**: Provides a graphical user interface for easy interaction and report generation.
24 | - **Customizable**: Adaptable to organizational needs and scalable for diverse IT environments.
25 | - **Accurate Reporting**: Reliable and precise in identifying deviations from best practices.
26 | - **Easy Updates**: Facilitates straightforward updates to accommodate changes in CIS benchmarks over time.
27 |
28 | ## Installation
29 |
30 | To set up the Automated CIS Benchmark Auditing Tool, follow these steps:
31 |
32 | 1. Clone the repository:
33 | ```sh
34 | git clone https://github.com/ethical-buddy/SIH24.git
35 | ```
36 | 2. Navigate to the project directory:
37 | ```sh
38 | cd automated-cis-benchmark-auditing-tool
39 | ```
40 | 3. Install dependencies:
41 | ```sh
42 | python go_install.py
43 | ```
44 |
45 | ## What This Script Does
46 |
47 | This Python script automates the setup and execution of an auditing tool for CIS benchmarks. Here’s a step-by-step overview of its functionality:
48 |
49 | 1. **Operating System Detection and Go Installation**:
50 | - Detects your operating system.
51 | - Installs Go (Golang) if it is not already present on your system.
52 |
53 | 2. **Run the Main Application**:
54 | - Executes the `main.go` file, which launches the graphical user interface (GUI) for the auditing tool.
55 |
56 | 3. **Run Audit**:
57 | - Within the GUI, initiate the auditing process. The tool will scan your system and compare configurations against the selected CIS benchmarks.
58 |
59 | 4. **Generate Report**:
60 | - Upon completion of the audit, the tool will generate a detailed report of the findings, which you can review and save.
61 |
62 | ## Usage
63 |
64 | This script performs system tests to ensure compliance with CIS Benchmarks. It does not modify any system files.
65 |
66 | ### GUI Options
67 |
68 | **Filters:**
69 |
70 | - `help`: Show this help message and exit.
71 | - `level {1,2}`: Run tests for the specified CIS benchmark level only.
72 | - `include INCLUDES [INCLUDES ...]`: Specify a space-delimited list of tests to include in the audit.
73 | - `exclude EXCLUDES [EXCLUDES ...]`: Specify a space-delimited list of tests to exclude from the audit.
74 | - `l {DEBUG,INFO,WARNING,CRITICAL}`, `log-level {DEBUG,INFO,WARNING,CRITICAL}`: Set the logging output level.
75 | - `debug`: Enable debug output. This is equivalent to setting the log level to DEBUG.
76 | - `nice`: Lower the CPU priority for test execution. This is the default behavior.
77 | - `no-nice`: Do not lower CPU priority. This may speed up the tests but increase server load. Overrides `--nice`.
78 | - `no-colour`, `no-color`: Disable colored output for STDOUT. Note that output redirected to a file or pipe will not be colored regardless.
79 | - `system-type {server,workstation}`: Specify which test levels to use.
80 | - `server`: Use "server" levels for tests. This is the default.
81 | - `workstation`: Use "workstation" levels for tests.
82 | - `outformat {csv,json,psv,text,tsv}`: Define the format for output results.
83 | - `text`: Output results as plain text (default).
84 | - `json`: Output results as JSON.
85 | - `csv`: Output results as comma-separated values.
86 | - `psv`: Output results as pipe-separated values.
87 | - `tsv`: Output results as tab-separated values.
88 | - `version`: Print the script version and exit.
89 | - `config CONFIG`: Specify the location of the configuration file to load.
90 |
91 | **Example Usage:**
92 |
93 |
94 |
95 |
96 |
97 | ## License
98 |
99 | This project is licensed under the [MIT License](LICENSE).
100 |
101 | ---
102 |
103 | Thank you for using the Automated CIS Benchmark Auditing Tool!
104 |
--------------------------------------------------------------------------------
/suryansh_d/python_vs_go:
--------------------------------------------------------------------------------
1 | 1. Performance
2 | Go:
3 |
4 | Fast Execution: Go is a compiled language, which means it generally runs faster than interpreted languages like Python. If performance is critical, especially for running complex or resource-intensive tasks, Go has the edge.
5 | Concurrency: Go has built-in support for concurrent programming with goroutines, making it ideal for tasks that can be parallelized.
6 | Python:
7 |
8 | Slower Execution: Python is an interpreted language, so it's generally slower than Go. However, for many tasks, the speed difference might not be significant enough to be a dealbreaker.
9 | Concurrency: Python’s Global Interpreter Lock (GIL) can be a limitation for multi-threaded tasks, although you can use multi-processing or async features for concurrency.
10 | 2. Ease of Use and Learning Curve
11 | Go:
12 |
13 | Simple Syntax: Go has a clean and simple syntax, but it requires more boilerplate code compared to Python.
14 | Learning Curve: While Go is relatively easy to learn, it has concepts like strict typing, pointers, and concurrency that may take some time to master if you're new to programming.
15 | Python:
16 |
17 | User-Friendly: Python is known for its readability and simplicity, making it an excellent choice for beginners or for rapid development.
18 | High-Level Abstractions: Python provides a lot of built-in functions and libraries, allowing you to accomplish tasks with minimal code.
19 | 3. Cross-Platform Compatibility
20 | Go:
21 |
22 | Native Cross-Compilation: Go allows you to easily compile binaries for different operating systems from the same codebase, making it highly suitable for cross-platform applications.
23 | Standard Library: Go’s standard library is robust and provides many cross-platform features out of the box.
24 | Python:
25 |
26 | Interpreted Language: Python runs on any platform with a compatible interpreter, which is nearly ubiquitous. However, distributing Python scripts usually requires ensuring the right interpreter and dependencies are installed.
27 | Virtual Environments: Python uses virtual environments for dependency management, which can add complexity when distributing scripts.
28 | 4. Ecosystem and Libraries
29 | Go:
30 |
31 | Standard Library: Go has a powerful standard library but fewer third-party libraries compared to Python. For system-level programming and networking, Go’s libraries are very strong.
32 | Community and Packages: The Go ecosystem is growing, but you might find fewer libraries for specific tasks compared to Python, especially for things like data analysis or machine learning.
33 | Python:
34 |
35 | Rich Ecosystem: Python has an extensive ecosystem with libraries for virtually any task, from web development to data science. For audit scripting, libraries like os, subprocess, shutil, and others are readily available.
36 | Community Support: Python has a vast and active community, making it easy to find support, tutorials, and pre-built solutions for common tasks.
37 | 5. Development Speed and Flexibility
38 | Go:
39 |
40 | Explicitness: Go forces you to be explicit in your coding, which can reduce bugs but may slow down development initially.
41 | Tooling: Go has excellent tooling for building, testing, and deploying applications, which can streamline the development process.
42 | Python:
43 |
44 | Rapid Development: Python’s simplicity and extensive libraries allow for rapid prototyping and development. It’s particularly good for scripting and automating tasks quickly.
45 | Flexibility: Python’s dynamic typing and high-level nature make it very flexible, allowing for fast iteration and experimentation.
46 | 6. Deployment
47 | Go:
48 |
49 | Static Binaries: Go produces standalone, statically-linked binaries that don’t require external dependencies, making deployment straightforward.
50 | Size: Go binaries can be larger, but they are self-contained, simplifying distribution.
51 | Python:
52 |
53 | Interpreter Required: Python scripts typically require a Python interpreter to be installed on the target system, and managing dependencies can be complex.
54 | Packaging: Tools like PyInstaller or cx_Freeze can bundle Python scripts into standalone executables, but this process can be more involved than with Go.
55 | 7. Use Cases
56 | Go:
57 |
58 | System-Level Tasks: Go is well-suited for system-level programming, network services, and applications where performance and concurrency are important.
59 | Enterprise and Cloud: Go is increasingly popular for cloud services, microservices, and distributed systems.
60 | Python:
61 |
62 | Automation and Scripting: Python excels at writing automation scripts, glue code, and tasks that involve a lot of text processing or interaction with other software.
63 | Data Science and AI: Python dominates in areas like data science, machine learning, and AI, thanks to its vast ecosystem of libraries.
64 | Which One Should You Choose?
65 | Go might be better if:
66 |
67 | Performance and concurrency are crucial.
68 | You need a single, self-contained binary for easy deployment.
69 | You're working on system-level tasks or need to interact closely with the OS.
70 | Your team is comfortable with stricter typing and a slightly steeper learning curve.
71 | Python might be better if:
72 |
73 | Rapid development and ease of use are your top priorities.
74 | You need to leverage a rich ecosystem of libraries for various tasks.
75 | The project involves a lot of scripting, automation, or interaction with other software.
76 | Your team is more familiar with Python, or you prefer a language that’s easier to learn.
77 |
78 |
--------------------------------------------------------------------------------
/suryansh_d/flow.txt:
--------------------------------------------------------------------------------
1 | 1. Project Structure Setup
2 | We'll create a directory structure that will help organize the project files effectively:
3 |
4 | bash
5 | Copy code
6 | cis-benchmark-audit-tool/
7 | │
8 | ├── cmd/ # Contains main application entry points
9 | │ ├── windows/ # Windows-specific main function
10 | │ │ └── main.go
11 | │ └── linux/ # Linux-specific main function
12 | │ └── main.go
13 | │
14 | ├── internal/ # Core logic and business rules
15 | │ ├── benchmarks/ # Benchmark checks
16 | │ │ ├── windows.go # Windows-specific checks
17 | │ │ └── linux.go # Linux-specific checks
18 | │ ├── report/ # Report generation logic
19 | │ │ └── report.go
20 | │ ├── gui/ # GUI-related logic
21 | │ │ └── gui.go
22 | │ └── config/ # Configuration management
23 | │ └── config.go
24 | │
25 | ├── assets/ # Static assets like icons, stylesheets, etc.
26 | │ └── logo.png
27 | │
28 | └── go.mod # Go module file
29 | 2. Task Understanding
30 | The goal is to create a tool that:
31 |
32 | Audits systems based on CIS benchmarks.
33 | Supports both Windows and Linux platforms.
34 | Offers a GUI for user interaction.
35 | Utilizes multithreading to handle multiple checks concurrently.
36 | Allows user customization for which benchmarks to check.
37 | 3. Implementation Steps
38 | 3.1 Benchmark Check Tool
39 | We'll start by creating simple benchmark check functions for both Windows and Linux. The focus will be on modularity, making it easy to add more checks later.
40 |
41 | Windows Benchmark Check (windows.go)
42 | go
43 | Copy code
44 | package benchmarks
45 |
46 | import (
47 | "fmt"
48 | "os/exec"
49 | )
50 |
51 | func CheckWindowsFirewall() (string, error) {
52 | cmd := exec.Command("powershell", "Get-NetFirewallProfile | Select-Object -Property Name, Enabled")
53 | output, err := cmd.CombinedOutput()
54 | if err != nil {
55 | return "", err
56 | }
57 | return string(output), nil
58 | }
59 | Linux Benchmark Check (linux.go)
60 | go
61 | Copy code
62 | package benchmarks
63 |
64 | import (
65 | "fmt"
66 | "os/exec"
67 | )
68 |
69 | func CheckLinuxFirewall() (string, error) {
70 | cmd := exec.Command("ufw", "status")
71 | output, err := cmd.CombinedOutput()
72 | if err != nil {
73 | return "", err
74 | }
75 | return string(output), nil
76 | }
77 | These are basic examples for checking firewall status. More functions can be added for other benchmarks.
78 |
79 | 3.2 Adding Multithreading
80 | To run multiple checks concurrently, we'll use Goroutines.
81 |
82 | go
83 | Copy code
84 | package benchmarks
85 |
86 | import (
87 | "fmt"
88 | "sync"
89 | )
90 |
91 | func RunWindowsChecks() {
92 | var wg sync.WaitGroup
93 | checks := []func() (string, error){
94 | CheckWindowsFirewall,
95 | // Add more check functions here
96 | }
97 |
98 | for _, check := range checks {
99 | wg.Add(1)
100 | go func(chk func() (string, error)) {
101 | defer wg.Done()
102 | result, err := chk()
103 | if err != nil {
104 | fmt.Println("Error:", err)
105 | return
106 | }
107 | fmt.Println(result)
108 | }(check)
109 | }
110 | wg.Wait()
111 | }
112 | 3.3 Report Generation
113 | Create a basic report generator that collects and formats the results from each check.
114 |
115 | go
116 | Copy code
117 | package report
118 |
119 | import (
120 | "os"
121 | "fmt"
122 | )
123 |
124 | type Report struct {
125 | Results []string
126 | }
127 |
128 | func (r *Report) AddResult(result string) {
129 | r.Results = append(r.Results, result)
130 | }
131 |
132 | func (r *Report) GenerateReport(filename string) error {
133 | file, err := os.Create(filename)
134 | if err != nil {
135 | return err
136 | }
137 | defer file.Close()
138 |
139 | for _, result := range r.Results {
140 | _, err := file.WriteString(result + "\n")
141 | if err != nil {
142 | return err
143 | }
144 | }
145 | fmt.Println("Report generated:", filename)
146 | return nil
147 | }
148 | 3.4 GUI Creation
149 | For the GUI, we'll use a Go library like fyne to create a cross-platform graphical interface. Below is a basic setup.
150 |
151 | go
152 | Copy code
153 | package gui
154 |
155 | import (
156 | "fyne.io/fyne/v2/app"
157 | "fyne.io/fyne/v2/container"
158 | "fyne.io/fyne/v2/widget"
159 | )
160 |
161 | func CreateGUI() {
162 | myApp := app.New()
163 | myWindow := myApp.NewWindow("CIS Benchmark Audit Tool")
164 |
165 | startButton := widget.NewButton("Start Audit", func() {
166 | // Trigger audit functions here
167 | })
168 |
169 | myWindow.SetContent(container.NewVBox(
170 | widget.NewLabel("Welcome to the CIS Benchmark Audit Tool!"),
171 | startButton,
172 | ))
173 |
174 | myWindow.ShowAndRun()
175 | }
176 | 3.5 Main Function Setup
177 | We'll have different entry points for Windows and Linux to ensure platform-specific checks are run.
178 |
179 | Windows Main (main.go)
180 | go
181 | Copy code
182 | package main
183 |
184 | import (
185 | "cis-benchmark-audit-tool/internal/benchmarks"
186 | "cis-benchmark-audit-tool/internal/gui"
187 | )
188 |
189 | func main() {
190 | go benchmarks.RunWindowsChecks()
191 | gui.CreateGUI()
192 | }
193 | Linux Main (main.go)
194 | go
195 | Copy code
196 | package main
197 |
198 | import (
199 | "cis-benchmark-audit-tool/internal/benchmarks"
200 | "cis-benchmark-audit-tool/internal/gui"
201 | )
202 |
203 | func main() {
204 | go benchmarks.RunLinuxChecks()
205 | gui.CreateGUI()
206 | }
207 | 4. Customizability
208 | To make the tool customizable, add a configuration management module. Users should be able to define which benchmarks to run.
209 |
210 | go
211 | Copy code
212 | package config
213 |
214 | import (
215 | "encoding/json"
216 | "os"
217 | )
218 |
219 | type Config struct {
220 | WindowsChecks []string `json:"windows_checks"`
221 | LinuxChecks []string `json:"linux_checks"`
222 | }
223 |
224 | func LoadConfig(filename string) (*Config, error) {
225 | file, err := os.Open(filename)
226 | if err != nil {
227 | return nil, err
228 | }
229 | defer file.Close()
230 |
231 | var config Config
232 | decoder := json.NewDecoder(file)
233 | err = decoder.Decode(&config)
234 | if err != nil {
235 | return nil, err
236 | }
237 | return &config, nil
238 | }
239 | 5. Enhancement Path
240 | Add More Checks: Implement additional benchmark checks in windows.go and linux.go.
241 | Enhanced GUI: Add more interactive elements like checkboxes for selecting benchmarks.
242 | Improved Reporting: Expand the report generation to include more details and format options (e.g., JSON, HTML).
243 | Automatic Updates: Implement a mechanism to update benchmarks from the CIS website.
244 | 6. Conclusion
245 | This is the foundational structure for your CIS Benchmark Audit Tool. Each part is modular, allowing you to expand the checks, improve the GUI, and customize it to your needs. Start by implementing the basic checks and GUI, then iteratively add more features and refinements. With this structure, you'll have a robust and scalable tool by the end of your project.
246 |
247 |
248 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/gui/gui.go:
--------------------------------------------------------------------------------
1 | package gui
2 |
3 | import (
4 | "bytes"
5 | "cis-benchmark-audit-tool/internal/benchmarks"
6 | "html/template"
7 | "io/ioutil"
8 | "log"
9 | // "os"
10 | "os/exec"
11 | "runtime"
12 |
13 | "fyne.io/fyne/v2"
14 | "fyne.io/fyne/v2/app"
15 | "fyne.io/fyne/v2/canvas"
16 | "fyne.io/fyne/v2/container"
17 | "fyne.io/fyne/v2/widget"
18 | )
19 |
20 | func CreateGUI() {
21 | // Create a new Fyne application
22 | myApp := app.New()
23 |
24 | // Create a new window
25 | myWindow := myApp.NewWindow("CIS Benchmark Audit Tool")
26 | myWindow.Resize(fyne.NewSize(800, 600)) // Set window size
27 | myWindow.CenterOnScreen()
28 |
29 | // Load and display a logo from the assets directory
30 | imageData, err := ioutil.ReadFile("assets/logo.png")
31 | if err != nil {
32 | log.Fatal("Failed to load logo image:", err)
33 | }
34 | logo := canvas.NewImageFromReader(bytes.NewReader(imageData), "logo.png")
35 | logo.FillMode = canvas.ImageFillOriginal
36 |
37 | // Create a text area for displaying audit results
38 | resultArea := widget.NewMultiLineEntry()
39 | resultArea.SetPlaceHolder("Audit results will be displayed here...")
40 | resultArea.Wrapping = fyne.TextWrapWord
41 | resultArea.Disable()
42 |
43 | // Create a dropdown with checkboxes for selecting benchmarks
44 | benchmarkCheckboxes := map[string]*widget.Check{
45 | "RunLinuxCheck1": widget.NewCheck("CheckLinuxFirewall", nil),
46 | "RunLinuxCheck2": widget.NewCheck("DisableCramfs", nil),
47 | "RunLinuxCheck3": widget.NewCheck("DisableFreevxfs", nil),
48 | "RunLinuxCheck4": widget.NewCheck("DisableJffs2", nil),
49 | "RunLinuxCheck5": widget.NewCheck("DisableHfs", nil),
50 | "RunLinuxCheck6": widget.NewCheck("DisableSquashfs", nil),
51 | "RunLinuxCheck7": widget.NewCheck("DisableUdf", nil),
52 | "RunLinuxCheck8": widget.NewCheck("EnsureTmpIsSeparatePartition", nil),
53 | "RunLinuxCheck9": widget.NewCheck("EnsureNodevOnTmp", nil),
54 | "RunLinuxCheck10": widget.NewCheck("EnsureNoexecOnTmp", nil),
55 | "RunLinuxCheck11": widget.NewCheck("EnsureNosuidOnTmp", nil),
56 | "RunLinuxCheck12": widget.NewCheck("EnsureSeparateVarPartition", nil),
57 | "RunLinuxCheck13": widget.NewCheck("EnsureNodevOnVar", nil),
58 | "RunLinuxCheck14": widget.NewCheck("EnsureNosuidOnVar", nil),
59 | "RunLinuxCheck15": widget.NewCheck("EnsureSeparateVarTmpPartition", nil),
60 | "RunLinuxCheck16": widget.NewCheck("EnsureNodevOnVarTmp", nil),
61 | "RunLinuxCheck17": widget.NewCheck("EnsureSeparateVarLogPartition", nil),
62 | "RunLinuxCheck18": widget.NewCheck("EnsureNoexecOnVarLog", nil),
63 | "RunLinuxCheck19": widget.NewCheck("EnsureNosuidOnVarLog", nil),
64 | "RunLinuxCheck20": widget.NewCheck("EnsureSeparateVarLogAuditPartition", nil),
65 | "RunLinuxCheck22": widget.NewCheck("EnsureNoexecOnVarLogAudit", nil),
66 | "RunLinuxCheck23": widget.NewCheck("EnsureNosuidOnVarLogAudit", nil),
67 | "RunLinuxCheck24": widget.NewCheck("EnsureNodevOnHome", nil),
68 | "RunLinuxCheck25": widget.NewCheck("EnsureNosuidOnHome", nil),
69 | "RunLinuxCheck26": widget.NewCheck("EnsureNodevOnDevShm", nil),
70 | "RunLinuxCheck27": widget.NewCheck("EnsureNoexecOnDevShm", nil),
71 | "RunLinuxCheck28": widget.NewCheck("EnsureNosuidOnDevShm", nil),
72 | "RunLinuxCheck29": widget.NewCheck("EnsureAutomountingDisabled", nil),
73 | "RunLinuxCheck30": widget.NewCheck("EnsureUSBStorageDisabled", nil),
74 | }
75 |
76 | // Create a VBox to hold the checkboxes
77 | checkboxContainer := container.NewVBox()
78 |
79 | // Create the "Select All" checkbox
80 | selectAllCheckbox := widget.NewCheck("Select All", func(checked bool) {
81 | for _, check := range benchmarkCheckboxes {
82 | check.SetChecked(checked)
83 | }
84 | })
85 |
86 | // Add the "Select All" checkbox to the container
87 | checkboxContainer.Add(selectAllCheckbox)
88 |
89 | // Add individual benchmark checkboxes to the container
90 | for _, check := range benchmarkCheckboxes {
91 | checkboxContainer.Add(check)
92 | }
93 |
94 | // Create a scrollable container for the checkboxes
95 | scrollableCheckboxContainer := container.NewScroll(checkboxContainer)
96 | scrollableCheckboxContainer.SetMinSize(fyne.NewSize(250, 350)) // Set a minimum size for visibility
97 |
98 | // Create a button to trigger the dropdown
99 | benchmarkButton := widget.NewButton("Select Benchmarks", func() {
100 | // Display the scrollable checkboxes as a pop-up
101 | benchmarkMenu := widget.NewPopUp(scrollableCheckboxContainer, myWindow.Canvas())
102 | benchmarkMenu.ShowAtPosition(fyne.NewPos(myWindow.Canvas().Size().Width-230, 40)) // Adjust position as needed
103 | })
104 |
105 | var benchmarkFunctions = map[string]func() (string, error){
106 | // Benchmark functions
107 | "RunLinuxCheck1": benchmarks.CheckLinuxFirewall,
108 | "RunLinuxCheck2": benchmarks.DisableCramfs,
109 | "RunLinuxCheck3": benchmarks.DisableFreevxfs,
110 | "RunLinuxCheck4": benchmarks.DisableJffs2,
111 | "RunLinuxCheck5": benchmarks.DisableHfs,
112 | "RunLinuxCheck6": benchmarks.DisableSquashfs,
113 | "RunLinuxCheck7": benchmarks.DisableUdf,
114 | "RunLinuxCheck8": benchmarks.EnsureTmpIsSeparatePartition,
115 | "RunLinuxCheck9": benchmarks.EnsureNodevOnTmp,
116 | "RunLinuxCheck10": benchmarks.EnsureNoexecOnTmp,
117 | "RunLinuxCheck11": benchmarks.EnsureNosuidOnTmp,
118 | "RunLinuxCheck12": benchmarks.EnsureSeparateVarPartition,
119 | "RunLinuxCheck13": benchmarks.EnsureNodevOnVar,
120 | "RunLinuxCheck14": benchmarks.EnsureNosuidOnVar,
121 | "RunLinuxCheck15": benchmarks.EnsureSeparateVarTmpPartition,
122 | "RunLinuxCheck16": benchmarks.EnsureNodevOnVarTmp,
123 | "RunLinuxCheck17": benchmarks.EnsureSeparateVarLogPartition,
124 | "RunLinuxCheck18": benchmarks.EnsureNoexecOnVarLog,
125 | "RunLinuxCheck19": benchmarks.EnsureNosuidOnVarLog,
126 | "RunLinuxCheck20": benchmarks.EnsureSeparateVarLogAuditPartition,
127 | "RunLinuxCheck22": benchmarks.EnsureNoexecOnVarLogAudit,
128 | "RunLinuxCheck23": benchmarks.EnsureNosuidOnVarLogAudit,
129 | "RunLinuxCheck24": benchmarks.EnsureNodevOnHome,
130 | "RunLinuxCheck25": benchmarks.EnsureNosuidOnHome,
131 | "RunLinuxCheck26": benchmarks.EnsureNodevOnDevShm,
132 | "RunLinuxCheck27": benchmarks.EnsureNoexecOnDevShm,
133 | "RunLinuxCheck28": benchmarks.EnsureNosuidOnDevShm,
134 | "RunLinuxCheck29": benchmarks.EnsureAutomountingDisabled,
135 | "RunLinuxCheck30": benchmarks.EnsureUSBStorageDisabled,
136 | }
137 |
138 | // Create a mapping from function identifiers to descriptive names
139 | functionNameMapping := map[string]string{
140 | "RunLinuxCheck1": "Check Linux Firewall",
141 | "RunLinuxCheck2": "Disable Cramfs",
142 | "RunLinuxCheck3": "Disable Freevxfs",
143 | "RunLinuxCheck4": "Disable Jffs2",
144 | "RunLinuxCheck5": "Disable Hfs",
145 | "RunLinuxCheck6": "Disable Squashfs",
146 | "RunLinuxCheck7": "Disable Udf",
147 | "RunLinuxCheck8": "Ensure /tmp is a Separate Partition",
148 | "RunLinuxCheck9": "Ensure nodev option on /tmp",
149 | "RunLinuxCheck10": "Ensure noexec option on /tmp",
150 | "RunLinuxCheck11": "Ensure nosuid option on /tmp",
151 | "RunLinuxCheck12": "Ensure /var is a Separate Partition",
152 | "RunLinuxCheck13": "Ensure nodev option on /var",
153 | "RunLinuxCheck14": "Ensure nosuid option on /var",
154 | "RunLinuxCheck15": "Ensure /var/tmp is a Separate Partition",
155 | "RunLinuxCheck16": "Ensure nodev option on /var/tmp",
156 | "RunLinuxCheck17": "Ensure /var/log is a Separate Partition",
157 | "RunLinuxCheck18": "Ensure noexec option on /var/log",
158 | "RunLinuxCheck19": "Ensure nosuid option on /var/log",
159 | "RunLinuxCheck20": "Ensure /var/log/audit is a Separate Partition",
160 | "RunLinuxCheck22": "Ensure noexec option on /var/log/audit",
161 | "RunLinuxCheck23": "Ensure nosuid option on /var/log/audit",
162 | "RunLinuxCheck24": "Ensure nodev option on /home",
163 | "RunLinuxCheck25": "Ensure nosuid option on /home",
164 | "RunLinuxCheck26": "Ensure nodev option on /dev/shm",
165 | "RunLinuxCheck27": "Ensure noexec option on /dev/shm",
166 | "RunLinuxCheck28": "Ensure nosuid option on /dev/shm",
167 | "RunLinuxCheck29": "Ensure automounting is Disabled",
168 | "RunLinuxCheck30": "Ensure USB Storage is Disabled",
169 | }
170 |
171 | // Create a button to start the audit
172 | startButton := widget.NewButton("Start Audit", func() {
173 | go func() {
174 | var results string
175 | for id, check := range benchmarkCheckboxes {
176 | if check.Checked {
177 | if benchmarkFunc, exists := benchmarkFunctions[id]; exists {
178 | result, err := benchmarkFunc()
179 | if err != nil {
180 | results += functionNameMapping[id] + " failed: " + err.Error() + "\n"
181 | } else {
182 | results += functionNameMapping[id] + " passed: " + result + "\n"
183 | }
184 | }
185 | }
186 | }
187 |
188 | // Generate the HTML report
189 | htmlFileName := "audit_report.html"
190 | tmpl := template.Must(template.New("report").Parse(`
191 |
192 |
193 |
194 |
195 |
196 | CIS Benchmark Audit Report
197 |
218 |
219 |
220 |
221 |
224 |
225 | {{ .Results }}
226 |
227 |
230 |
231 |
232 |
233 | `))
234 | var buf bytes.Buffer
235 | data := struct {
236 | Results string
237 | }{
238 | Results: results,
239 | }
240 | err = tmpl.Execute(&buf, data)
241 | if err != nil {
242 | log.Println("Failed to generate HTML report:", err)
243 | return
244 | }
245 |
246 | err = ioutil.WriteFile(htmlFileName, buf.Bytes(), 0644)
247 | if err != nil {
248 | log.Println("Failed to save HTML report:", err)
249 | return
250 | }
251 |
252 | resultArea.SetText(results)
253 |
254 | // Add functionality to convert HTML to PDF
255 | if runtime.GOOS == "linux" {
256 | err = exec.Command("wkhtmltopdf", htmlFileName, "audit_report.pdf").Run()
257 | if err != nil {
258 | log.Println("Failed to convert HTML to PDF:", err)
259 | }
260 | } else {
261 | log.Println("PDF conversion is only supported on Linux.")
262 | }
263 | }()
264 | })
265 |
266 | // Create a button to open the file
267 | openFileButton := widget.NewButton("Open Report", func() {
268 | if err := exec.Command("xdg-open", "audit_report.html").Run(); err != nil {
269 | log.Println("Failed to open HTML report:", err)
270 | }
271 | })
272 |
273 | // Create a container for the buttons
274 | buttonsContainer := container.NewHBox(startButton, openFileButton)
275 |
276 | // Create the main layout
277 | mainContent := container.NewVBox(
278 | logo,
279 | benchmarkButton,
280 | buttonsContainer,
281 | resultArea,
282 | )
283 |
284 | myWindow.SetContent(mainContent)
285 | myWindow.ShowAndRun()
286 | }
287 |
288 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/benchmarks/windows.go:
--------------------------------------------------------------------------------
1 | package benchmarks
2 |
3 | import (
4 | //"fmt"
5 | "os/exec"
6 | )
7 |
8 | // CheckWindowsFirewall checks the status of the Windows Firewall profiles.
9 | func CheckWindowsFirewall() (string, error) {
10 | cmd := exec.Command("powershell", "Get-NetFirewallProfile | Select-Object -Property Name, Enabled")
11 | output, err := cmd.CombinedOutput()
12 | if err != nil {
13 | return "", err
14 | }
15 | return string(output), nil
16 | }
17 |
18 | // EnsurePasswordHistory checks if 'Enforce password history' is set to '24 or more passwords'.
19 | func EnsurePasswordHistory() (string, error) {
20 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
21 | err := cmd.Run()
22 | if err != nil {
23 | return "", err
24 | }
25 | return "Password history policy enforced", nil
26 | }
27 |
28 | // EnsureMaximumPasswordAge checks if 'Maximum password age' is set to '365 or fewer days, but not 0'.
29 | func EnsureMaximumPasswordAge() (string, error) {
30 | cmd := exec.Command("net", "accounts", "/MAXPWAGE:365")
31 | err := cmd.Run()
32 | if err != nil {
33 | return "", err
34 | }
35 | return "Maximum password age set to 365 days", nil
36 | }
37 |
38 | // EnsureMinimumPasswordAge checks if 'Minimum password age' is set to '1 or more days'.
39 | func EnsureMinimumPasswordAge() (string, error) {
40 | cmd := exec.Command("net", "accounts", "/MINPWAGE:1")
41 | err := cmd.Run()
42 | if err != nil {
43 | return "", err
44 | }
45 | return "Minimum password age set to 1 day", nil
46 | }
47 |
48 | // EnsureMinimumPasswordLength checks if 'Minimum password length' is set to '14 or more characters'.
49 | func EnsureMinimumPasswordLength() (string, error) {
50 | cmd := exec.Command("net", "accounts", "/MINPWLEN:14")
51 | err := cmd.Run()
52 | if err != nil {
53 | return "", err
54 | }
55 | return "Minimum password length set to 14 characters", nil
56 | }
57 |
58 | // EnsurePasswordComplexity checks if 'Password must meet complexity requirements' is set to 'Enabled'.
59 | func EnsurePasswordComplexity() (string, error) {
60 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
61 | err := cmd.Run()
62 | if err != nil {
63 | return "", err
64 | }
65 | return "Password complexity requirements enforced", nil
66 | }
67 |
68 | // EnsureRelaxMinimumPasswordLength checks if 'Relax minimum password length limits' is set to 'Enabled'.
69 | func EnsureRelaxMinimumPasswordLength() (string, error) {
70 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
71 | err := cmd.Run()
72 | if err != nil {
73 | return "", err
74 | }
75 | return "Minimum password length limits relaxed", nil
76 | }
77 |
78 | // EnsureStorePasswordsReversibleEncryption checks if 'Store passwords using reversible encryption' is set to 'Disabled'.
79 | func EnsureStorePasswordsReversibleEncryption() (string, error) {
80 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
81 | err := cmd.Run()
82 | if err != nil {
83 | return "", err
84 | }
85 | return "Reversible encryption for storing passwords disabled", nil
86 | }
87 |
88 | // EnsureAccountLockoutDuration checks if 'Account lockout duration' is set to '15 or more minutes'.
89 | func EnsureAccountLockoutDuration() (string, error) {
90 | cmd := exec.Command("net", "accounts", "/LOCKOUTDURATION:15")
91 | err := cmd.Run()
92 | if err != nil {
93 | return "", err
94 | }
95 | return "Account lockout duration set to 15 minutes", nil
96 | }
97 |
98 | // EnsureAccountLockoutThreshold checks if 'Account lockout threshold' is set to '5 or fewer invalid logon attempts, but not 0'.
99 | func EnsureAccountLockoutThreshold() (string, error) {
100 | cmd := exec.Command("net", "accounts", "/LOCKOUTTHRESHOLD:5")
101 | err := cmd.Run()
102 | if err != nil {
103 | return "", err
104 | }
105 | return "Account lockout threshold set to 5 attempts", nil
106 | }
107 |
108 | // EnsureAdministratorAccountLockout checks if 'Allow Administrator account lockout' is set to 'Enabled'.
109 | func EnsureAdministratorAccountLockout() (string, error) {
110 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
111 | err := cmd.Run()
112 | if err != nil {
113 | return "", err
114 | }
115 | return "Administrator account lockout enabled", nil
116 | }
117 |
118 | // EnsureResetAccountLockoutCounter checks if 'Reset account lockout counter after' is set to '15 or more minutes'.
119 | func EnsureResetAccountLockoutCounter() (string, error) {
120 | cmd := exec.Command("net", "accounts", "/LOCKOUTWINDOW:15")
121 | err := cmd.Run()
122 | if err != nil {
123 | return "", err
124 | }
125 | return "Account lockout counter reset time set to 15 minutes", nil
126 | }
127 |
128 | // EnsureCredentialManagerAccess checks if 'Access Credential Manager as a trusted caller' is set to 'No One'.
129 | func EnsureCredentialManagerAccess() (string, error) {
130 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
131 | err := cmd.Run()
132 | if err != nil {
133 | return "", err
134 | }
135 | return "Credential Manager access set to No One", nil
136 | }
137 |
138 | // EnsureNetworkAccess is set to 'Administrators, Remote Desktop Users'.
139 | func EnsureNetworkAccess() (string, error) {
140 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
141 | err := cmd.Run()
142 | if err != nil {
143 | return "", err
144 | }
145 | return "Network access limited to Administrators and Remote Desktop Users", nil
146 | }
147 |
148 | // EnsureActAsOs is set to 'No One'.
149 | func EnsureActAsOs() (string, error) {
150 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
151 | err := cmd.Run()
152 | if err != nil {
153 | return "", err
154 | }
155 | return "Act as part of the operating system is restricted to No One", nil
156 | }
157 |
158 | // EnsureMemoryQuotas is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE'.
159 | func EnsureMemoryQuotas() (string, error) {
160 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
161 | err := cmd.Run()
162 | if err != nil {
163 | return "", err
164 | }
165 | return "Memory quotas set for Administrators, LOCAL SERVICE, NETWORK SERVICE", nil
166 | }
167 |
168 | // EnsureLogonLocally is set to 'Administrators, Users'.
169 | func EnsureLogonLocally() (string, error) {
170 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
171 | err := cmd.Run()
172 | if err != nil {
173 | return "", err
174 | }
175 | return "Local logon limited to Administrators and Users", nil
176 | }
177 |
178 | // EnsureRemoteDesktopLogon is set to 'Administrators, Remote Desktop Users'.
179 | func EnsureRemoteDesktopLogon() (string, error) {
180 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
181 | err := cmd.Run()
182 | if err != nil {
183 | return "", err
184 | }
185 | return "Remote Desktop logon limited to Administrators and Remote Desktop Users", nil
186 | }
187 |
188 | // EnsureCreatePagefile checks if 'Create a pagefile' is set to 'Administrators'.
189 | func EnsureCreatePagefile() (string, error) {
190 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
191 | err := cmd.Run()
192 | if err != nil {
193 | return "", err
194 | }
195 | return "Create a pagefile set to Administrators", nil
196 | }
197 |
198 | // EnsureCreateTokenObject checks if 'Create a token object' is set to 'No One'.
199 | func EnsureCreateTokenObject() (string, error) {
200 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
201 | err := cmd.Run()
202 | if err != nil {
203 | return "", err
204 | }
205 | return "Create a token object set to No One", nil
206 | }
207 |
208 | // EnsureCreateGlobalObjects checks if 'Create global objects' is set to 'Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE'.
209 | func EnsureCreateGlobalObjects() (string, error) {
210 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
211 | err := cmd.Run()
212 | if err != nil {
213 | return "", err
214 | }
215 | return "Create global objects set to Administrators, LOCAL SERVICE, NETWORK SERVICE, SERVICE", nil
216 | }
217 |
218 | // EnsureDenyLogonLocally checks if 'Deny log on locally' is set to include 'Guests'.
219 | func EnsureDenyLogonLocally() (string, error) {
220 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
221 | err := cmd.Run()
222 | if err != nil {
223 | return "", err
224 | }
225 | return "Deny log on locally set to include Guests", nil
226 | }
227 |
228 | // EnsureDenyLogonThroughRemoteDesktop checks if 'Deny log on through Remote Desktop Services' is set to include 'Guests, Local account'.
229 | func EnsureDenyLogonThroughRemoteDesktop() (string, error) {
230 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
231 | err := cmd.Run()
232 | if err != nil {
233 | return "", err
234 | }
235 | return "Deny log on through Remote Desktop Services set to include Guests, Local account", nil
236 | }
237 |
238 | // EnsureForceShutdownFromRemoteSystem checks if 'Force shutdown from a remote system' is set to 'Administrators'.
239 | func EnsureForceShutdownFromRemoteSystem() (string, error) {
240 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
241 | err := cmd.Run()
242 | if err != nil {
243 | return "", err
244 | }
245 | return "Force shutdown from a remote system set to Administrators", nil
246 | }
247 |
248 | // EnsureGenerateSecurityAudits checks if 'Generate security audits' is set to 'LOCAL SERVICE, NETWORK SERVICE'.
249 | func EnsureGenerateSecurityAudits() (string, error) {
250 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
251 | err := cmd.Run()
252 | if err != nil {
253 | return "", err
254 | }
255 | return "Generate security audits set to LOCAL SERVICE, NETWORK SERVICE", nil
256 | }
257 |
258 | // EnsureIncreaseSchedulingPriority checks if 'Increase scheduling priority' is set to 'Administrators, Window Manager\\Window Manager Group'.
259 | func EnsureIncreaseSchedulingPriority() (string, error) {
260 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
261 | err := cmd.Run()
262 | if err != nil {
263 | return "", err
264 | }
265 | return "Increase scheduling priority set to Administrators, Window Manager\\Window Manager Group", nil
266 | }
267 |
268 | // EnsureLoadUnloadDeviceDrivers checks if 'Load and unload device drivers' is set to 'Administrators'.
269 | func EnsureLoadUnloadDeviceDrivers() (string, error) {
270 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
271 | err := cmd.Run()
272 | if err != nil {
273 | return "", err
274 | }
275 | return "Load and unload device drivers set to Administrators", nil
276 | }
277 |
278 | // EnsureAccountsBlockMicrosoftAccounts checks if 'Accounts: Block Microsoft accounts' is set to 'Users can't add or log on with Microsoft accounts'.
279 | func EnsureAccountsBlockMicrosoftAccounts() (string, error) {
280 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
281 | err := cmd.Run()
282 | if err != nil {
283 | return "", err
284 | }
285 | return "Accounts: Block Microsoft accounts set to 'Users can't add or log on with Microsoft accounts'", nil
286 | }
287 |
288 | // EnsureGuestAccountStatus checks if 'Accounts: Guest account status' is set to 'Disabled'.
289 | func EnsureGuestAccountStatus() (string, error) {
290 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
291 | err := cmd.Run()
292 | if err != nil {
293 | return "", err
294 | }
295 | return "Accounts: Guest account status set to Disabled", nil
296 | }
297 |
298 | // EnsureLimitBlankPasswordUsage checks if 'Accounts: Limit local account use of blank passwords to console logon only' is set to 'Enabled'.
299 | func EnsureLimitBlankPasswordUsage() (string, error) {
300 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
301 | err := cmd.Run()
302 | if err != nil {
303 | return "", err
304 | }
305 | return "Accounts: Limit local account use of blank passwords to console logon only set to Enabled", nil
306 | }
307 |
308 | // EnsureAuditForceAuditPolicySubcategorySettings checks if 'Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings' is set to 'Enabled'.
309 | func EnsureAuditForceAuditPolicySubcategorySettings() (string, error) {
310 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
311 | err := cmd.Run()
312 | if err != nil {
313 | return "", err
314 | }
315 | return "Audit: Force audit policy subcategory settings (Windows Vista or later) to override audit policy category settings set to Enabled", nil
316 | }
317 |
318 | // EnsureAuditShutDownSystemIfUnableToLogSecurityAudits checks if 'Audit: Shut down system immediately if unable to log security audits' is set to 'Disabled'.
319 | func EnsureAuditShutDownSystemIfUnableToLogSecurityAudits() (string, error) {
320 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
321 | err := cmd.Run()
322 | if err != nil {
323 | return "", err
324 | }
325 | return "Audit: Shut down system immediately if unable to log security audits set to Disabled", nil
326 | }
327 |
328 | // EnsureDCOMRestrictions checks if 'DCOM: Machine Access Restrictions in Security Descriptor Definition Language (SDDL) syntax' is set to 'Enabled'.
329 | func EnsureDCOMRestrictions() (string, error) {
330 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
331 | err := cmd.Run()
332 | if err != nil {
333 | return "", err
334 | }
335 | return "DCOM: Machine Access Restrictions set to Enabled", nil
336 | }
337 |
338 | // EnsureDomainMemberDisableMachineAccountPasswordChanges checks if 'Domain member: Disable machine account password changes' is set to 'Disabled'.
339 | func EnsureDomainMemberDisableMachineAccountPasswordChanges() (string, error) {
340 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
341 | err := cmd.Run()
342 | if err != nil {
343 | return "", err
344 | }
345 | return "Domain member: Disable machine account password changes set to Disabled", nil
346 | }
347 |
348 | // EnsureDomainMemberMaxMachineAccountPasswordAge checks if 'Domain member: Maximum machine account password age' is set to '30 or fewer days, but not 0'.
349 | func EnsureDomainMemberMaxMachineAccountPasswordAge() (string, error) {
350 | cmd := exec.Command("net", "accounts", "/MAXPWAGE:30")
351 | err := cmd.Run()
352 | if err != nil {
353 | return "", err
354 | }
355 | return "Domain member: Maximum machine account password age set to 30 or fewer days", nil
356 | }
357 |
358 | // EnsureDomainMemberRequireStrongSessionKey checks if 'Domain member: Require strong (Windows 2000 or later) session key' is set to 'Enabled'.
359 | func EnsureDomainMemberRequireStrongSessionKey() (string, error) {
360 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
361 | err := cmd.Run()
362 | if err != nil {
363 | return "", err
364 | }
365 | return "Domain member: Require strong (Windows 2000 or later) session key set to Enabled", nil
366 | }
367 |
368 | // EnsureInteractiveLogonDoNotRequireCtrlAltDel checks if 'Interactive logon: Do not require CTRL+ALT+DEL' is set to 'Disabled'.
369 | func EnsureInteractiveLogonDoNotRequireCtrlAltDel() (string, error) {
370 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
371 | err := cmd.Run()
372 | if err != nil {
373 | return "", err
374 | }
375 | return "Interactive logon: Do not require CTRL+ALT+DEL set to Disabled", nil
376 | }
377 |
378 | // EnsureInteractiveLogonDontDisplayLastSignedIn checks if 'Interactive logon: Don't display last signed-in' is set to 'Enabled'.
379 | func EnsureInteractiveLogonDontDisplayLastSignedIn() (string, error) {
380 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
381 | err := cmd.Run()
382 | if err != nil {
383 | return "", err
384 | }
385 | return "Interactive logon: Don't display last signed-in set to Enabled", nil
386 | }
387 |
388 | // EnsureInteractiveLogonMachineAccountLockoutThreshold checks if 'Interactive logon: Machine account lockout threshold' is set to '10 or fewer invalid logon attempts, but not 0'.
389 | func EnsureInteractiveLogonMachineAccountLockoutThreshold() (string, error) {
390 | cmd := exec.Command("net", "accounts", "/LOCKOUTTHRESHOLD:10")
391 | err := cmd.Run()
392 | if err != nil {
393 | return "", err
394 | }
395 | return "Interactive logon: Machine account lockout threshold set to 10 or fewer invalid logon attempts", nil
396 | }
397 |
398 | // EnsureInteractiveLogonMachineInactivityLimit checks if 'Interactive logon: Machine inactivity limit' is set to '900 or fewer seconds, but not 0'.
399 | func EnsureInteractiveLogonMachineInactivityLimit() (string, error) {
400 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
401 | err := cmd.Run()
402 | if err != nil {
403 | return "", err
404 | }
405 | return "Interactive logon: Machine inactivity limit set to 900 or fewer seconds", nil
406 | }
407 |
408 | // EnsureNetworkAccessLetEveryonePermissionsApplyToAnonymousUsers checks if 'Network access: Let Everyone permissions apply to anonymous users' is set to 'Disabled'.
409 | func EnsureNetworkAccessLetEveryonePermissionsApplyToAnonymousUsers() (string, error) {
410 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
411 | err := cmd.Run()
412 | if err != nil {
413 | return "", err
414 | }
415 | return "Network access: Let Everyone permissions apply to anonymous users set to Disabled", nil
416 | }
417 |
418 | // EnsureNetworkAccessDoNotAllowAnonymousEnumOfSAMAccountsAndShares checks if 'Network access: Do not allow anonymous enumeration of SAM accounts and shares' is set to 'Enabled'.
419 | func EnsureNetworkAccessDoNotAllowAnonymousEnumOfSAMAccountsAndShares() (string, error) {
420 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
421 | err := cmd.Run()
422 | if err != nil {
423 | return "", err
424 | }
425 | return "Network access: Do not allow anonymous enumeration of SAM accounts and shares set to Enabled", nil
426 | }
427 |
428 | // EnsureNetworkAccessRestrictAnonymousAccessToNamedPipesAndShares checks if 'Network access: Restrict anonymous access to Named Pipes and Shares' is set to 'Enabled'.
429 | func EnsureNetworkAccessRestrictAnonymousAccessToNamedPipesAndShares() (string, error) {
430 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
431 | err := cmd.Run()
432 | if err != nil {
433 | return "", err
434 | }
435 | return "Network access: Restrict anonymous access to Named Pipes and Shares set to Enabled", nil
436 | }
437 |
438 | // EnsureNetworkSecurityLANManagerAuthenticationLevel checks if 'Network security: LAN Manager authentication level' is set to 'Send NTLMv2 response only. Refuse LM & NTLM'.
439 | func EnsureNetworkSecurityLANManagerAuthenticationLevel() (string, error) {
440 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
441 | err := cmd.Run()
442 | if err != nil {
443 | return "", err
444 | }
445 | return "Network security: LAN Manager authentication level set to 'Send NTLMv2 response only. Refuse LM & NTLM'", nil
446 | }
447 |
448 | // EnsureNetworkSecurityDoNotStoreLANManagerHashValue checks if 'Network security: Do not store LAN Manager hash value on next password change' is set to 'Enabled'.
449 | func EnsureNetworkSecurityDoNotStoreLANManagerHashValue() (string, error) {
450 | cmd := exec.Command("secedit", "/export", "/cfg", "secpol.cfg")
451 | err := cmd.Run()
452 | if err != nil {
453 | return "", err
454 | }
455 | return "Network security: Do not store LAN Manager hash value on next password change set to Enabled", nil
456 | }
457 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/internal/benchmarks/linux.go:
--------------------------------------------------------------------------------
1 | package benchmarks
2 |
3 | import (
4 | "fmt"
5 | "os/exec"
6 | "strings"
7 | "sync"
8 | )
9 |
10 | // CheckLinuxFirewall checks the status of the firewall
11 | func CheckLinuxFirewall() (string, error) {
12 | cmd := exec.Command("ufw", "status")
13 | output, err := cmd.CombinedOutput()
14 | if err != nil {
15 | return "", err
16 | }
17 | return string(output), nil
18 | }
19 |
20 | // DisableCramfs disables the cramfs module
21 | func DisableCramfs() (string, error) {
22 | denyCmd := exec.Command("sh", "-c", `echo "install cramfs /bin/false" >> /etc/modprobe.d/cramfs.conf && echo "blacklist cramfs" >> /etc/modprobe.d/cramfs.conf`)
23 | if err := denyCmd.Run(); err != nil {
24 | return "", fmt.Errorf("Failed to deny list cramfs: %v", err)
25 | }
26 | unloadCmd := exec.Command("sh", "-c", "modprobe -r cramfs")
27 | if err := unloadCmd.Run(); err != nil {
28 | return "", fmt.Errorf("Failed to unload cramfs: %v", err)
29 | }
30 | return "cramfs module disabled successfully.", nil
31 | }
32 |
33 | // DisableFreevxfs disables the freevxfs module
34 | func DisableFreevxfs() (string, error) {
35 | denyCmd := exec.Command("sh", "-c", `echo "install freevxfs /bin/false" >> /etc/modprobe.d/freevxfs.conf && echo "blacklist freevxfs" >> /etc/modprobe.d/freevxfs.conf`)
36 | if err := denyCmd.Run(); err != nil {
37 | return "", fmt.Errorf("Failed to deny list freevxfs: %v", err)
38 | }
39 | unloadCmd := exec.Command("sh", "-c", "modprobe -r freevxfs")
40 | if err := unloadCmd.Run(); err != nil {
41 | return "", fmt.Errorf("Failed to unload freevxfs: %v", err)
42 | }
43 | return "freevxfs module disabled successfully.", nil
44 | }
45 |
46 | // DisableJffs2 disables the jffs2 module
47 | func DisableJffs2() (string, error) {
48 | denyCmd := exec.Command("sh", "-c", `echo "install jffs2 /bin/false" >> /etc/modprobe.d/jffs2.conf && echo "blacklist jffs2" >> /etc/modprobe.d/jffs2.conf`)
49 | if err := denyCmd.Run(); err != nil {
50 | return "", fmt.Errorf("Failed to deny list jffs2: %v", err)
51 | }
52 | unloadCmd := exec.Command("sh", "-c", "modprobe -r jffs2")
53 | if err := unloadCmd.Run(); err != nil {
54 | return "", fmt.Errorf("Failed to unload jffs2: %v", err)
55 | }
56 | return "jffs2 module disabled successfully.", nil
57 | }
58 |
59 | // DisableHfs disables the hfs module
60 | func DisableHfs() (string, error) {
61 | denyCmd := exec.Command("sh", "-c", `echo "install hfs /bin/false" >> /etc/modprobe.d/hfs.conf && echo "blacklist hfs" >> /etc/modprobe.d/hfs.conf`)
62 | if err := denyCmd.Run(); err != nil {
63 | return "", fmt.Errorf("Failed to deny list hfs: %v", err)
64 | }
65 | unloadCmd := exec.Command("sh", "-c", "modprobe -r hfs")
66 | if err := unloadCmd.Run(); err != nil {
67 | return "", fmt.Errorf("Failed to unload hfs: %v", err)
68 | }
69 | return "hfs module disabled successfully.", nil
70 | }
71 |
72 | // DisableHfsplus disables the hfsplus module
73 | func DisableHfsplus() (string, error) {
74 | denyCmd := exec.Command("sh", "-c", `echo "install hfsplus /bin/false" >> /etc/modprobe.d/hfsplus.conf && echo "blacklist hfsplus" >> /etc/modprobe.d/hfsplus.conf`)
75 | if err := denyCmd.Run(); err != nil {
76 | return "", fmt.Errorf("Failed to deny list hfsplus: %v", err)
77 | }
78 | unloadCmd := exec.Command("sh", "-c", "modprobe -r hfsplus")
79 | if err := unloadCmd.Run(); err != nil {
80 | return "", fmt.Errorf("Failed to unload hfsplus: %v", err)
81 | }
82 | return "hfsplus module disabled successfully.", nil
83 | }
84 |
85 | // DisableSquashfs disables the squashfs module
86 | func DisableSquashfs() (string, error) {
87 | denyCmd := exec.Command("sh", "-c", `echo "install squashfs /bin/false" >> /etc/modprobe.d/squashfs.conf && echo "blacklist squashfs" >> /etc/modprobe.d/squashfs.conf`)
88 | if err := denyCmd.Run(); err != nil {
89 | return "", fmt.Errorf("Failed to deny list squashfs: %v", err)
90 | }
91 | unloadCmd := exec.Command("sh", "-c", "modprobe -r squashfs")
92 | if err := unloadCmd.Run(); err != nil {
93 | return "", fmt.Errorf("Failed to unload squashfs: %v", err)
94 | }
95 | return "squashfs module disabled successfully.", nil
96 | }
97 |
98 | // DisableUdf disables the udf module
99 | func DisableUdf() (string, error) {
100 | denyCmd := exec.Command("sh", "-c", `echo "install udf /bin/false" >> /etc/modprobe.d/udf.conf && echo "blacklist udf" >> /etc/modprobe.d/udf.conf`)
101 | if err := denyCmd.Run(); err != nil {
102 | return "", fmt.Errorf("Failed to deny list udf: %v", err)
103 | }
104 | unloadCmd := exec.Command("sh", "-c", "modprobe -r udf")
105 | if err := unloadCmd.Run(); err != nil {
106 | return "", fmt.Errorf("Failed to unload udf: %v", err)
107 | }
108 | return "udf module disabled successfully.", nil
109 | }
110 |
111 | // EnsureTmpIsSeparatePartition checks if /tmp is a separate partition
112 | func EnsureTmpIsSeparatePartition() (string, error) {
113 | checkCmd := exec.Command("sh", "-c", `findmnt -n /tmp | cut -d " " -f 1`)
114 | output, err := checkCmd.CombinedOutput()
115 | if err != nil {
116 | return "", fmt.Errorf("Failed to check /tmp partition: %v", err)
117 | }
118 | if string(output) == "/tmp" {
119 | return "/tmp is already a separate partition.", nil
120 | }
121 | return "", fmt.Errorf("/tmp is not a separate partition")
122 | }
123 |
124 | // EnsureNodevOnTmp ensures nodev option is set on /tmp partition
125 | func EnsureNodevOnTmp() (string, error) {
126 | checkCmd := exec.Command("sh", "-c", `findmnt -n /tmp | grep -q "nodev"`)
127 | if err := checkCmd.Run(); err != nil {
128 | return "", fmt.Errorf("nodev option is not set on /tmp partition")
129 | }
130 | return "nodev option is set on /tmp partition.", nil
131 | }
132 |
133 | // EnsureNoexecOnTmp ensures noexec option is set on /tmp partition
134 | func EnsureNoexecOnTmp() (string, error) {
135 | checkCmd := exec.Command("sh", "-c", `findmnt -n /tmp | grep -q "noexec"`)
136 | if err := checkCmd.Run(); err != nil {
137 | return "", fmt.Errorf("noexec option is not set on /tmp partition")
138 | }
139 | return "noexec option is set on /tmp partition.", nil
140 | }
141 |
142 | // EnsureNosuidOnTmp ensures nosuid option is set on /tmp partition
143 | func EnsureNosuidOnTmp() (string, error) {
144 | checkCmd := exec.Command("sh", "-c", `findmnt -n /tmp | grep -q "nosuid"`)
145 | if err := checkCmd.Run(); err != nil {
146 | return "", fmt.Errorf("nosuid option is not set on /tmp partition")
147 | }
148 | return "nosuid option is set on /tmp partition.", nil
149 | }
150 |
151 | // EnsureSeparateVarPartition checks if /var is a separate partition
152 | func EnsureSeparateVarPartition() (string, error) {
153 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var | cut -d " " -f 1`)
154 | output, err := checkCmd.CombinedOutput()
155 | if err != nil {
156 | return "", fmt.Errorf("Failed to check /var partition: %v", err)
157 | }
158 | if string(output) == "/var" {
159 | return "/var is already a separate partition.", nil
160 | }
161 | return "", fmt.Errorf("/var is not a separate partition")
162 | }
163 |
164 | // EnsureNodevOnVar ensures nodev option is set on /var partition
165 | func EnsureNodevOnVar() (string, error) {
166 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var | grep -q "nodev"`)
167 | if err := checkCmd.Run(); err != nil {
168 | return "", fmt.Errorf("nodev option is not set on /var partition")
169 | }
170 | return "nodev option is set on /var partition.", nil
171 | }
172 |
173 | // EnsureNosuidOnVar ensures nosuid option is set on /var partition
174 | func EnsureNosuidOnVar() (string, error) {
175 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var | grep -q "nosuid"`)
176 | if err := checkCmd.Run(); err != nil {
177 | return "", fmt.Errorf("nosuid option is not set on /var partition")
178 | }
179 | return "nosuid option is set on /var partition.", nil
180 | }
181 |
182 | // EnsureSeparateVarTmpPartition checks if /var/tmp is a separate partition
183 | func EnsureSeparateVarTmpPartition() (string, error) {
184 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/tmp | cut -d " " -f 1`)
185 | output, err := checkCmd.CombinedOutput()
186 | if err != nil {
187 | return "", fmt.Errorf("Failed to check /var/tmp partition: %v", err)
188 | }
189 | if string(output) == "/var/tmp" {
190 | return "/var/tmp is already a separate partition.", nil
191 | }
192 | return "", fmt.Errorf("/var/tmp is not a separate partition")
193 | }
194 |
195 | // EnsureNodevOnVarTmp ensures nodev option is set on /var/tmp partition
196 | func EnsureNodevOnVarTmp() (string, error) {
197 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/tmp | grep -q "nodev"`)
198 | if err := checkCmd.Run(); err != nil {
199 | return "", fmt.Errorf("nodev option is not set on /var/tmp partition")
200 | }
201 | return "nodev option is set on /var/tmp partition.", nil
202 | }
203 |
204 | // EnsureNoexecOnVarTmp ensures noexec option is set on /var/tmp partition
205 | func EnsureNoexecOnVarTmp() (string, error) {
206 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/tmp | grep -q "noexec"`)
207 | if err := checkCmd.Run(); err != nil {
208 | return "", fmt.Errorf("noexec option is not set on /var/tmp partition")
209 | }
210 | return "noexec option is set on /var/tmp partition.", nil
211 | }
212 |
213 | // EnsureNosuidOnVarTmp ensures nosuid option is set on /var/tmp partition
214 | func EnsureNosuidOnVarTmp() (string, error) {
215 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/tmp | grep -q "nosuid"`)
216 | if err := checkCmd.Run(); err != nil {
217 | return "", fmt.Errorf("nosuid option is not set on /var/tmp partition")
218 | }
219 | return "nosuid option is set on /var/tmp partition.", nil
220 | }
221 |
222 | // EnsureSeparateVarLogPartition checks if /var/log is a separate partition
223 | func EnsureSeparateVarLogPartition() (string, error) {
224 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/log | cut -d " " -f 1`)
225 | output, err := checkCmd.CombinedOutput()
226 | if err != nil {
227 | return "", fmt.Errorf("Failed to check /var/log partition: %v", err)
228 | }
229 | if string(output) == "/var/log" {
230 | return "/var/log is already a separate partition.", nil
231 | }
232 | return "", fmt.Errorf("/var/log is not a separate partition")
233 | }
234 |
235 | // EnsureNoexecOnVarLog ensures noexec option is set on /var/log partition
236 | func EnsureNoexecOnVarLog() (string, error) {
237 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/log | grep -q "noexec"`)
238 | if err := checkCmd.Run(); err != nil {
239 | return "", fmt.Errorf("noexec option is not set on /var/log partition")
240 | }
241 | return "noexec option is set on /var/log partition.", nil
242 | }
243 |
244 | // EnsureNosuidOnVarLog ensures nosuid option is set on /var/log partition
245 | func EnsureNosuidOnVarLog() (string, error) {
246 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/log | grep -q "nosuid"`)
247 | if err := checkCmd.Run(); err != nil {
248 | return "", fmt.Errorf("nosuid option is not set on /var/log partition")
249 | }
250 | return "nosuid option is set on /var/log partition.", nil
251 | }
252 |
253 | // EnsureSeparateVarLogAuditPartition checks if /var/log/audit is a separate partition
254 | func EnsureSeparateVarLogAuditPartition() (string, error) {
255 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/log/audit | cut -d " " -f 1`)
256 | output, err := checkCmd.CombinedOutput()
257 | if err != nil {
258 | return "", fmt.Errorf("Failed to check /var/log/audit partition: %v", err)
259 | }
260 | if string(output) == "/var/log/audit" {
261 | return "/var/log/audit is already a separate partition.", nil
262 | }
263 | return "", fmt.Errorf("/var/log/audit is not a separate partition")
264 | }
265 |
266 | // EnsureNoexecOnVarLogAudit ensures noexec option is set on /var/log/audit partition
267 | func EnsureNoexecOnVarLogAudit() (string, error) {
268 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/log/audit | grep -q "noexec"`)
269 | if err := checkCmd.Run(); err != nil {
270 | return "", fmt.Errorf("noexec option is not set on /var/log/audit partition")
271 | }
272 | return "noexec option is set on /var/log/audit partition.", nil
273 | }
274 |
275 | // EnsureNosuidOnVarLogAudit ensures nosuid option is set on /var/log/audit partition
276 | func EnsureNosuidOnVarLogAudit() (string, error) {
277 | checkCmd := exec.Command("sh", "-c", `findmnt -n /var/log/audit | grep -q "nosuid"`)
278 | if err := checkCmd.Run(); err != nil {
279 | return "", fmt.Errorf("nosuid option is not set on /var/log/audit partition")
280 | }
281 | return "nosuid option is set on /var/log/audit partition.", nil
282 | }
283 |
284 | // EnsureSeparateHomePartition checks if /home is a separate partition
285 | func EnsureSeparateHomePartition() (string, error) {
286 | checkCmd := exec.Command("sh", "-c", `findmnt -n /home | cut -d " " -f 1`)
287 | output, err := checkCmd.CombinedOutput()
288 | if err != nil {
289 | return "", fmt.Errorf("Failed to check /home partition: %v", err)
290 | }
291 | if string(output) == "/home" {
292 | return "/home is already a separate partition.", nil
293 | }
294 | return "", fmt.Errorf("/home is not a separate partition")
295 | }
296 |
297 | // EnsureNodevOnHome ensures nodev option is set on /home partition
298 | func EnsureNodevOnHome() (string, error) {
299 | checkCmd := exec.Command("sh", "-c", `findmnt -n /home | grep -q "nodev"`)
300 | if err := checkCmd.Run(); err != nil {
301 | return "", fmt.Errorf("nodev option is not set on /home partition")
302 | }
303 | return "nodev option is set on /home partition.", nil
304 | }
305 |
306 | // EnsureNosuidOnHome ensures nosuid option is set on /home partition
307 | func EnsureNosuidOnHome() (string, error) {
308 | checkCmd := exec.Command("sh", "-c", `findmnt -n /home | grep -q "nosuid"`)
309 | if err := checkCmd.Run(); err != nil {
310 | return "", fmt.Errorf("nosuid option is not set on /home partition")
311 | }
312 | return "nosuid option is set on /home partition.", nil
313 | }
314 |
315 | // EnsureNodevOnDevShm ensures nodev option is set on /dev/shm partition
316 | func EnsureNodevOnDevShm() (string, error) {
317 | checkCmd := exec.Command("sh", "-c", `findmnt -n /dev/shm | grep -q "nodev"`)
318 | if err := checkCmd.Run(); err != nil {
319 | return "", fmt.Errorf("nodev option is not set on /dev/shm partition")
320 | }
321 | return "nodev option is set on /dev/shm partition.", nil
322 | }
323 |
324 | // EnsureNoexecOnDevShm ensures noexec option is set on /dev/shm partition
325 | func EnsureNoexecOnDevShm() (string, error) {
326 | checkCmd := exec.Command("sh", "-c", `findmnt -n /dev/shm | grep -q "noexec"`)
327 | if err := checkCmd.Run(); err != nil {
328 | return "", fmt.Errorf("noexec option is not set on /dev/shm partition")
329 | }
330 | return "noexec option is set on /dev/shm partition.", nil
331 | }
332 |
333 | // EnsureNosuidOnDevShm ensures nosuid option is set on /dev/shm partition
334 | func EnsureNosuidOnDevShm() (string, error) {
335 | checkCmd := exec.Command("sh", "-c", `findmnt -n /dev/shm | grep -q "nosuid"`)
336 | if err := checkCmd.Run(); err != nil {
337 | return "", fmt.Errorf("nosuid option is not set on /dev/shm partition")
338 | }
339 | return "nosuid option is set on /dev/shm partition.", nil
340 | }
341 |
342 | // EnsureAutomountingDisabled ensures automounting is disabled
343 | func EnsureAutomountingDisabled() (string, error) {
344 | checkCmd := exec.Command("sh", "-c", `systemctl is-enabled autofs`)
345 | output, err := checkCmd.CombinedOutput()
346 | if err != nil {
347 | return "", fmt.Errorf("Failed to check automounting status: %v", err)
348 | }
349 | if strings.TrimSpace(string(output)) == "disabled" {
350 | return "Automounting is already disabled.", nil
351 | }
352 | return "", fmt.Errorf("Automounting is not disabled")
353 | }
354 |
355 | // EnsureUSBStorageDisabled ensures USB storage is disabled
356 | func EnsureUSBStorageDisabled() (string, error) {
357 | disableCmd := exec.Command("sh", "-c", `echo "install usb-storage /bin/false" >> /etc/modprobe.d/usb-storage.conf`)
358 | if err := disableCmd.Run(); err != nil {
359 | return "", fmt.Errorf("Failed to disable USB storage: %v", err)
360 | }
361 | return "USB storage disabled successfully.", nil
362 | }
363 |
364 | // EnsureGPGKeysConfigured checks if GPG keys are configured
365 | func EnsureGPGKeysConfigured() (string, error) {
366 | cmd := exec.Command("apt-key", "list")
367 | output, err := cmd.CombinedOutput()
368 | if err != nil {
369 | return "", fmt.Errorf("Failed to list GPG keys: %v", err)
370 | }
371 | if len(output) == 0 {
372 | return "", fmt.Errorf("No GPG keys configured")
373 | }
374 | return "GPG keys are configured.", nil
375 | }
376 |
377 | // EnsureAppArmorInstalled checks if AppArmor is installed
378 | func EnsureAppArmorInstalled() (string, error) {
379 | cmd := exec.Command("dpkg-query", "-W", "--showformat='${Status}'", "apparmor")
380 | output, err := cmd.CombinedOutput()
381 | if err != nil {
382 | return "", fmt.Errorf("Failed to check AppArmor installation: %v", err)
383 | }
384 | if !strings.Contains(string(output), "install ok installed") {
385 | return "", fmt.Errorf("AppArmor is not installed")
386 | }
387 | return "AppArmor is installed.", nil
388 | }
389 |
390 | // EnsureAppArmorEnabledInBootloader checks if AppArmor is enabled in the bootloader configuration
391 | func EnsureAppArmorEnabledInBootloader() (string, error) {
392 | cmd := exec.Command("grep", "'^\\s*linux'", "/boot/grub/grub.cfg")
393 | output, err := cmd.CombinedOutput()
394 | if err != nil {
395 | return "", fmt.Errorf("Failed to check AppArmor in bootloader: %v", err)
396 | }
397 | if !strings.Contains(string(output), "security=apparmor") {
398 | return "", fmt.Errorf("AppArmor is not enabled in bootloader")
399 | }
400 | return "AppArmor is enabled in the bootloader configuration.", nil
401 | }
402 |
403 | // EnsureAIDEInstalled checks if AIDE is installed
404 | func EnsureAIDEInstalled() (string, error) {
405 | cmd := exec.Command("dpkg-query", "-W", "--showformat='${Status}'", "aide")
406 | output, err := cmd.CombinedOutput()
407 | if err != nil {
408 | return "", fmt.Errorf("Failed to check AIDE installation: %v", err)
409 | }
410 | if !strings.Contains(string(output), "install ok installed") {
411 | return "", fmt.Errorf("AIDE is not installed")
412 | }
413 | return "AIDE is installed.", nil
414 | }
415 |
416 | // EnsureUFWInstalled checks if ufw is installed
417 | func EnsureUFWInstalled() (string, error) {
418 | cmd := exec.Command("dpkg-query", "-W", "--showformat='${Status}'", "ufw")
419 | output, err := cmd.CombinedOutput()
420 | if err != nil {
421 | return "", fmt.Errorf("Failed to check ufw installation: %v", err)
422 | }
423 | if !strings.Contains(string(output), "install ok installed") {
424 | return "", fmt.Errorf("ufw is not installed")
425 | }
426 | return "ufw is installed.", nil
427 | }
428 |
429 | // EnsureChronyOrNTPInstalled ensures either chrony or ntp is installed
430 | func EnsureChronyOrNTPInstalled() (string, error) {
431 | cmd := exec.Command("sh", "-c", "dpkg-query -W chrony ntp")
432 | output, err := cmd.CombinedOutput()
433 | if err != nil {
434 | return "", fmt.Errorf("Failed to check chrony or ntp installation: %v", err)
435 | }
436 | if !strings.Contains(string(output), "chrony") && !strings.Contains(string(output), "ntp") {
437 | return "", fmt.Errorf("Neither chrony nor ntp is installed")
438 | }
439 | return "Chrony or NTP is installed.", nil
440 | }
441 |
442 | // EnsureX11ForwardingDisabled ensures X11 forwarding is disabled
443 | func EnsureX11ForwardingDisabled() (string, error) {
444 | cmd := exec.Command("grep", "^X11Forwarding", "/etc/ssh/sshd_config")
445 | output, err := cmd.CombinedOutput()
446 | if err != nil {
447 | return "", fmt.Errorf("Failed to check X11Forwarding setting: %v", err)
448 | }
449 | if strings.TrimSpace(string(output)) != "X11Forwarding no" {
450 | return "", fmt.Errorf("X11 forwarding is not disabled")
451 | }
452 | return "X11 forwarding is disabled.", nil
453 | }
454 |
455 | // EnsureTimeSynchronizationIsInUse ensures a time synchronization service is in use
456 | func EnsureTimeSynchronizationIsInUse() (string, error) {
457 | cmd := exec.Command("timedatectl", "show", "-p", "NTPSynchronized")
458 | output, err := cmd.CombinedOutput()
459 | if err != nil {
460 | return "", fmt.Errorf("Failed to check time synchronization: %v", err)
461 | }
462 | if !strings.Contains(string(output), "yes") {
463 | return "", fmt.Errorf("Time synchronization is not in use")
464 | }
465 | return "Time synchronization is in use.", nil
466 | }
467 |
468 | // EnsureNoUnnecessaryServices ensures there are no unnecessary services running
469 | func EnsureNoUnnecessaryServices() (string, error) {
470 | services := []string{"avahi-daemon", "cups", "smbd", "rpcbind"}
471 | for _, service := range services {
472 | cmd := exec.Command("systemctl", "is-enabled", service)
473 | output, err := cmd.CombinedOutput()
474 | if err == nil && strings.TrimSpace(string(output)) != "disabled" {
475 | return "", fmt.Errorf("%s service is running", service)
476 | }
477 | }
478 | return "No unnecessary services are running.", nil
479 | }
480 |
481 | // EnsureSSHRootLoginDisabled ensures root login over SSH is disabled
482 | func EnsureSSHRootLoginDisabled() (string, error) {
483 | cmd := exec.Command("grep", "^PermitRootLogin", "/etc/ssh/sshd_config")
484 | output, err := cmd.CombinedOutput()
485 | if err != nil {
486 | return "", fmt.Errorf("Failed to check PermitRootLogin setting: %v", err)
487 | }
488 | if strings.TrimSpace(string(output)) != "PermitRootLogin no" {
489 | return "", fmt.Errorf("Root login over SSH is not disabled")
490 | }
491 | return "Root login over SSH is disabled.", nil
492 | }
493 |
494 | // EnsureSSHPermitEmptyPasswordsDisabled ensures SSH does not allow empty passwords
495 | func EnsureSSHPermitEmptyPasswordsDisabled() (string, error) {
496 | cmd := exec.Command("grep", "^PermitEmptyPasswords", "/etc/ssh/sshd_config")
497 | output, err := cmd.CombinedOutput()
498 | if err != nil {
499 | return "", fmt.Errorf("Failed to check PermitEmptyPasswords setting: %v", err)
500 | }
501 | if strings.TrimSpace(string(output)) != "PermitEmptyPasswords no" {
502 | return "", fmt.Errorf("SSH allows empty passwords")
503 | }
504 | return "SSH does not allow empty passwords.", nil
505 | }
506 |
507 | // EnsurePasswordExpirationConfigured ensures password expiration is configured
508 | func EnsurePasswordExpirationConfigured() (string, error) {
509 | cmd := exec.Command("chage", "-l", "root")
510 | output, err := cmd.CombinedOutput()
511 | if err != nil {
512 | return "", fmt.Errorf("Failed to check password expiration: %v", err)
513 | }
514 | if !strings.Contains(string(output), "Password expires") {
515 | return "", fmt.Errorf("Password expiration is not configured")
516 | }
517 | return "Password expiration is configured.", nil
518 | }
519 |
520 | // EnsureSSHBannerConfigured ensures the SSH banner is configured
521 | func EnsureSSHBannerConfigured() (string, error) {
522 | cmd := exec.Command("grep", "^Banner", "/etc/ssh/sshd_config")
523 | output, err := cmd.CombinedOutput()
524 | if err != nil {
525 | return "", fmt.Errorf("Failed to check SSH banner setting: %v", err)
526 | }
527 | if !strings.Contains(string(output), "/etc/issue.net") {
528 | return "", fmt.Errorf("SSH banner is not configured")
529 | }
530 | return "SSH banner is configured.", nil
531 | }
532 |
533 | // EnsureNISClientNotInstalled ensures the NIS client is not installed
534 | func EnsureNISClientNotInstalled() (string, error) {
535 | cmd := exec.Command("dpkg-query", "-W", "--showformat='${Status}'", "nis")
536 | output, err := cmd.CombinedOutput()
537 | if err == nil && strings.Contains(string(output), "install ok installed") {
538 | return "", fmt.Errorf("NIS client is installed")
539 | }
540 | return "NIS client is not installed.", nil
541 | }
542 |
543 | // EnsureTelnetClientNotInstalled ensures the Telnet client is not installed
544 | func EnsureTelnetClientNotInstalled() (string, error) {
545 | cmd := exec.Command("dpkg-query", "-W", "--showformat='${Status}'", "telnet")
546 | output, err := cmd.CombinedOutput()
547 | if err == nil && strings.Contains(string(output), "install ok installed") {
548 | return "", fmt.Errorf("Telnet client is installed")
549 | }
550 | return "Telnet client is not installed.", nil
551 | }
552 |
553 | // EnsureFTPClientNotInstalled ensures the FTP client is not installed
554 | func EnsureFTPClientNotInstalled() (string, error) {
555 | cmd := exec.Command("dpkg-query", "-W", "--showformat='${Status}'", "ftp")
556 | output, err := cmd.CombinedOutput()
557 | if err == nil && strings.Contains(string(output), "install ok installed") {
558 | return "", fmt.Errorf("FTP client is installed")
559 | }
560 | return "FTP client is not installed.", nil
561 | }
562 |
563 | // EnsureIPv6IsDisabled ensures IPv6 is disabled if not in use
564 | func EnsureIPv6IsDisabled() (string, error) {
565 | cmd := exec.Command("sysctl", "net.ipv6.conf.all.disable_ipv6")
566 | output, err := cmd.CombinedOutput()
567 | if err != nil {
568 | return "", fmt.Errorf("Failed to check IPv6 status: %v", err)
569 | }
570 | if !strings.Contains(string(output), "= 1") {
571 | return "", fmt.Errorf("IPv6 is not disabled")
572 | }
573 | return "IPv6 is disabled.", nil
574 | }
575 |
576 | // EnsureRootOnlyHasUID0 ensures only root has UID 0
577 | func EnsureRootOnlyHasUID0() (string, error) {
578 | cmd := exec.Command("awk", "-F:", "'$3 == 0 {print $1}'", "/etc/passwd")
579 | output, err := cmd.CombinedOutput()
580 | if err != nil {
581 | return "", fmt.Errorf("Failed to check UID 0 accounts: %v", err)
582 | }
583 | if strings.TrimSpace(string(output)) != "root" {
584 | return "", fmt.Errorf("More than one account has UID 0")
585 | }
586 | return "Only root has UID 0.", nil
587 | }
588 |
589 | // EnsureSyslogIsInstalled ensures syslog is installed
590 | func EnsureSyslogIsInstalled() (string, error) {
591 | cmd := exec.Command("dpkg-query", "-W", "--showformat='${Status}'", "rsyslog")
592 | output, err := cmd.CombinedOutput()
593 | if err != nil {
594 | return "", fmt.Errorf("Failed to check syslog installation: %v", err)
595 | }
596 | if !strings.Contains(string(output), "install ok installed") {
597 | return "", fmt.Errorf("Syslog is not installed")
598 | }
599 | return "Syslog is installed.", nil
600 | }
601 |
602 | // EnsureIPForwardingDisabled ensures IP forwarding is disabled
603 | func EnsureIPForwardingDisabled() (string, error) {
604 | cmd := exec.Command("sysctl", "net.ipv4.ip_forward")
605 | output, err := cmd.CombinedOutput()
606 | if err != nil {
607 | return "", fmt.Errorf("Failed to check IP forwarding: %v", err)
608 | }
609 | if !strings.Contains(string(output), "= 0") {
610 | return "", fmt.Errorf("IP forwarding is not disabled")
611 | }
612 | return "IP forwarding is disabled.", nil
613 | }
614 |
615 | // EnsurePacketRedirectSendingDisabled ensures packet redirect sending is disabled
616 | func EnsurePacketRedirectSendingDisabled() (string, error) {
617 | cmd := exec.Command("sysctl", "net.ipv4.conf.all.send_redirects")
618 | output, err := cmd.CombinedOutput()
619 | if err != nil {
620 | return "", fmt.Errorf("Failed to check packet redirect sending: %v", err)
621 | }
622 | if !strings.Contains(string(output), "= 0") {
623 | return "", fmt.Errorf("Packet redirect sending is not disabled")
624 | }
625 | return "Packet redirect sending is disabled.", nil
626 | }
627 |
628 | // EnsureBogusICMPResponsesIgnored ensures bogus ICMP responses are ignored
629 | func EnsureBogusICMPResponsesIgnored() (string, error) {
630 | cmd := exec.Command("sysctl", "net.ipv4.icmp_ignore_bogus_error_responses")
631 | output, err := cmd.CombinedOutput()
632 | if err != nil {
633 | return "", fmt.Errorf("Failed to check bogus ICMP responses setting: %v", err)
634 | }
635 | if !strings.Contains(string(output), "= 1") {
636 | return "", fmt.Errorf("Bogus ICMP responses are not ignored")
637 | }
638 | return "Bogus ICMP responses are ignored.", nil
639 | }
640 |
641 | // EnsureBroadcastICMPRequestsIgnored ensures broadcast ICMP requests are ignored
642 | func EnsureBroadcastICMPRequestsIgnored() (string, error) {
643 | cmd := exec.Command("sysctl", "net.ipv4.icmp_echo_ignore_broadcasts")
644 | output, err := cmd.CombinedOutput()
645 | if err != nil {
646 | return "", fmt.Errorf("Failed to check broadcast ICMP requests setting: %v", err)
647 | }
648 | if !strings.Contains(string(output), "= 1") {
649 | return "", fmt.Errorf("Broadcast ICMP requests are not ignored")
650 | }
651 | return "Broadcast ICMP requests are ignored.", nil
652 | }
653 |
654 | // EnsureICMPRedirectAcceptanceDisabled ensures ICMP redirects are not accepted
655 | func EnsureICMPRedirectAcceptanceDisabled() (string, error) {
656 | cmd := exec.Command("sysctl", "net.ipv4.conf.all.accept_redirects")
657 | output, err := cmd.CombinedOutput()
658 | if err != nil {
659 | return "", fmt.Errorf("Failed to check ICMP redirect acceptance: %v", err)
660 | }
661 | if !strings.Contains(string(output), "= 0") {
662 | return "", fmt.Errorf("ICMP redirects are accepted")
663 | }
664 | return "ICMP redirects are not accepted.", nil
665 | }
666 |
667 | // EnsureSecureICMPRedirectAcceptanceDisabled ensures secure ICMP redirects are not accepted
668 | func EnsureSecureICMPRedirectAcceptanceDisabled() (string, error) {
669 | cmd := exec.Command("sysctl", "net.ipv4.conf.all.secure_redirects")
670 | output, err := cmd.CombinedOutput()
671 | if err != nil {
672 | return "", fmt.Errorf("Failed to check secure ICMP redirect acceptance: %v", err)
673 | }
674 | if !strings.Contains(string(output), "= 0") {
675 | return "", fmt.Errorf("Secure ICMP redirects are accepted")
676 | }
677 | return "Secure ICMP redirects are not accepted.", nil
678 | }
679 |
680 | // EnsureReversePathFilteringEnabled ensures reverse path filtering is enabled
681 | func EnsureReversePathFilteringEnabled() (string, error) {
682 | cmd := exec.Command("sysctl", "net.ipv4.conf.all.rp_filter")
683 | output, err := cmd.CombinedOutput()
684 | if err != nil {
685 | return "", fmt.Errorf("Failed to check reverse path filtering: %v", err)
686 | }
687 | if !strings.Contains(string(output), "= 1") {
688 | return "", fmt.Errorf("Reverse path filtering is not enabled")
689 | }
690 | return "Reverse path filtering is enabled.", nil
691 | }
692 |
693 | // EnsureSourceRoutedPacketsNotAccepted ensures source-routed packets are not accepted
694 | func EnsureSourceRoutedPacketsNotAccepted() (string, error) {
695 | cmd := exec.Command("sysctl", "net.ipv4.conf.all.accept_source_route")
696 | output, err := cmd.CombinedOutput()
697 | if err != nil {
698 | return "", fmt.Errorf("Failed to check source-routed packets acceptance: %v", err)
699 | }
700 | if !strings.Contains(string(output), "= 0") {
701 | return "", fmt.Errorf("Source-routed packets are accepted")
702 | }
703 | return "Source-routed packets are not accepted.", nil
704 | }
705 |
706 | // EnsureSuspiciousPacketsLogged ensures suspicious packets are logged
707 | func EnsureSuspiciousPacketsLogged() (string, error) {
708 | cmd := exec.Command("sysctl", "net.ipv4.conf.all.log_martians")
709 | output, err := cmd.CombinedOutput()
710 | if err != nil {
711 | return "", fmt.Errorf("Failed to check suspicious packets logging: %v", err)
712 | }
713 | if !strings.Contains(string(output), "= 1") {
714 | return "", fmt.Errorf("Suspicious packets are not logged")
715 | }
716 | return "Suspicious packets are logged.", nil
717 | }
718 |
719 | // EnsureTCPSYNCookiesEnabled ensures TCP SYN Cookies are enabled
720 | func EnsureTCPSYNCookiesEnabled() (string, error) {
721 | cmd := exec.Command("sysctl", "net.ipv4.tcp_syncookies")
722 | output, err := cmd.CombinedOutput()
723 | if err != nil {
724 | return "", fmt.Errorf("Failed to check TCP SYN Cookies setting: %v", err)
725 | }
726 | if !strings.Contains(string(output), "= 1") {
727 | return "", fmt.Errorf("TCP SYN Cookies are not enabled")
728 | }
729 | return "TCP SYN Cookies are enabled.", nil
730 | }
731 |
732 | // EnsureIPv6RouterAdvertisementsNotAccepted ensures IPv6 router advertisements are not accepted
733 | func EnsureIPv6RouterAdvertisementsNotAccepted() (string, error) {
734 | cmd := exec.Command("sysctl", "net.ipv6.conf.all.accept_ra")
735 | output, err := cmd.CombinedOutput()
736 | if err != nil {
737 | return "", fmt.Errorf("Failed to check IPv6 router advertisements acceptance: %v", err)
738 | }
739 | if !strings.Contains(string(output), "= 0") {
740 | return "", fmt.Errorf("IPv6 router advertisements are accepted")
741 | }
742 | return "IPv6 router advertisements are not accepted.", nil
743 | }
744 |
745 | // RunLinuxChecks runs all the defined checks
746 | func RunLinuxChecks() string {
747 | var wg sync.WaitGroup
748 | results := ""
749 |
750 | checks := []func() (string, error){
751 | CheckLinuxFirewall,
752 | DisableCramfs,
753 | DisableFreevxfs,
754 | DisableJffs2,
755 | DisableHfs,
756 | DisableHfsplus,
757 | DisableSquashfs,
758 | DisableUdf,
759 | EnsureTmpIsSeparatePartition,
760 | EnsureNodevOnTmp,
761 | EnsureNoexecOnTmp,
762 | EnsureNosuidOnTmp,
763 | EnsureSeparateVarPartition,
764 | EnsureNodevOnVar,
765 | EnsureNosuidOnVar,
766 | EnsureSeparateVarTmpPartition,
767 | EnsureNodevOnVarTmp,
768 | EnsureNoexecOnVarTmp,
769 | EnsureNosuidOnVarTmp,
770 | EnsureSeparateVarLogPartition,
771 | EnsureNoexecOnVarLog,
772 | EnsureNosuidOnVarLog,
773 | EnsureSeparateVarLogAuditPartition,
774 | EnsureNoexecOnVarLogAudit,
775 | EnsureNosuidOnVarLogAudit,
776 | EnsureSeparateHomePartition,
777 | EnsureNodevOnHome,
778 | EnsureNosuidOnHome,
779 | EnsureNodevOnDevShm,
780 | EnsureNoexecOnDevShm,
781 | EnsureNosuidOnDevShm,
782 | EnsureAutomountingDisabled,
783 | EnsureUSBStorageDisabled,
784 | EnsureGPGKeysConfigured,
785 | EnsureAppArmorInstalled,
786 | EnsureAppArmorEnabledInBootloader,
787 | EnsureAIDEInstalled,
788 | EnsureUFWInstalled,
789 | EnsureChronyOrNTPInstalled,
790 | EnsureX11ForwardingDisabled,
791 | EnsureTimeSynchronizationIsInUse,
792 | EnsureNoUnnecessaryServices,
793 | EnsureSSHRootLoginDisabled,
794 | EnsureSSHPermitEmptyPasswordsDisabled,
795 | EnsurePasswordExpirationConfigured,
796 | EnsureSSHBannerConfigured,
797 | EnsureNISClientNotInstalled,
798 | EnsureTelnetClientNotInstalled,
799 | EnsureFTPClientNotInstalled,
800 | EnsureIPv6IsDisabled,
801 | EnsureRootOnlyHasUID0,
802 | EnsureSyslogIsInstalled,
803 | EnsureIPForwardingDisabled,
804 | EnsurePacketRedirectSendingDisabled,
805 | EnsureBogusICMPResponsesIgnored,
806 | EnsureBroadcastICMPRequestsIgnored,
807 | EnsureICMPRedirectAcceptanceDisabled,
808 | EnsureSecureICMPRedirectAcceptanceDisabled,
809 | EnsureReversePathFilteringEnabled,
810 | EnsureSourceRoutedPacketsNotAccepted,
811 | EnsureSuspiciousPacketsLogged,
812 | EnsureTCPSYNCookiesEnabled,
813 | EnsureIPv6RouterAdvertisementsNotAccepted,
814 | // Add more Linux check functions here
815 | }
816 |
817 | for _, check := range checks {
818 | wg.Add(1)
819 | go func(chk func() (string, error)) {
820 | defer wg.Done()
821 | result, err := chk()
822 | if err != nil {
823 | results += "Error: " + err.Error() + "\n"
824 | return
825 | }
826 | results += result + "\n"
827 | }(check)
828 | }
829 | wg.Wait()
830 |
831 | return results
832 | }
833 |
--------------------------------------------------------------------------------
/suryansh_d/code/cis-benchmark-audit-tool/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
16 | cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
17 | cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
18 | cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
19 | cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
20 | cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
21 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
22 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
23 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
24 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
25 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
26 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
27 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
28 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
29 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
30 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
31 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
32 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
33 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
34 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
35 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
36 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
37 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
38 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
39 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
40 | fyne.io/fyne/v2 v2.5.1 h1:jd2mhQz0ViosZjhgR5l2bdCbc5HFqkYnTzEXX8UOC7I=
41 | fyne.io/fyne/v2 v2.5.1/go.mod h1:NdxEG8L7EVWo06/cYbXW11uA0X7UG8Q8j5CLebvTZi8=
42 | fyne.io/systray v1.11.0 h1:D9HISlxSkx+jHSniMBR6fCFOUjk1x/OOOJLa9lJYAKg=
43 | fyne.io/systray v1.11.0/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs=
44 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
45 | github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
46 | github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
47 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
48 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
49 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
50 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
51 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
52 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
53 | github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
54 | github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
55 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
56 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
57 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
58 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
59 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
60 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
61 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
62 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
63 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
64 | github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
65 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
66 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
67 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
68 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
69 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
70 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
71 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
72 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
73 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
74 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
75 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
76 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
77 | github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
78 | github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
79 | github.com/fredbi/uri v1.1.0 h1:OqLpTXtyRg9ABReqvDGdJPqZUxs8cyBDOMXBbskCaB8=
80 | github.com/fredbi/uri v1.1.0/go.mod h1:aYTUoAXBOq7BLfVJ8GnKmfcuURosB1xyHDIfWeC/iW4=
81 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
82 | github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
83 | github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
84 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe h1:A/wiwvQ0CAjPkuJytaD+SsXkPU0asQ+guQEIg1BJGX4=
85 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe/go.mod h1:d4clgH0/GrRwWjRzJJQXxT/h1TyuNSfF/X64zb/3Ggg=
86 | github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a h1:ybgRdYvAHTn93HW79bLiBiJwVL4jVeyGQRZMgImoeWs=
87 | github.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a/go.mod h1:gsGA2dotD4v0SR6PmPCYvS9JuOeMwAtmfvDE7mbYXMY=
88 | github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 h1:hnLq+55b7Zh7/2IRzWCpiTcAvjv/P8ERF+N7+xXbZhk=
89 | github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0=
90 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
91 | github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk=
92 | github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
93 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
94 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
95 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
96 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a h1:vxnBhFDDT+xzxf1jTJKMKZw3H0swfWk9RpWbBbDK5+0=
97 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
98 | github.com/go-text/render v0.1.1-0.20240418202334-dd62631dae9b h1:daoFn+Aw8EIQZO9kYWwHL01FqwwpCl2nTeVEYbsgRHk=
99 | github.com/go-text/render v0.1.1-0.20240418202334-dd62631dae9b/go.mod h1:jqEuNMenrmj6QRnkdpeaP0oKGFLDNhDkVKwGjsWWYU4=
100 | github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKwVvHw=
101 | github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI=
102 | github.com/go-text/typesetting-utils v0.0.0-20240329101916-eee87fb235a3 h1:levTnuLLUmpavLGbJYLJA7fQnKeS7P1eCdAlM+vReXk=
103 | github.com/go-text/typesetting-utils v0.0.0-20240329101916-eee87fb235a3/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o=
104 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
105 | github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
106 | github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
107 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
108 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
109 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
110 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
111 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
112 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
113 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
114 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
115 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
116 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
117 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
118 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
119 | github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
120 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
121 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
122 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
123 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
124 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
125 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
126 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
127 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
128 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
129 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
130 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
131 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
132 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
133 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
134 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
135 | github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
136 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
137 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
138 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
139 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
140 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
141 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
142 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
143 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
144 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
145 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
146 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
147 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
148 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
149 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
150 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
151 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
152 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
153 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
154 | github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
155 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
156 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
157 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
158 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
159 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
160 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
161 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
162 | github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
163 | github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
164 | github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
165 | github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
166 | github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
167 | github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
168 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
169 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
170 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
171 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
172 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
173 | github.com/gopherjs/gopherjs v0.0.0-20211219123610-ec9572f70e60/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
174 | github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
175 | github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
176 | github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY=
177 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
178 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
179 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
180 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
181 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
182 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
183 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
184 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
185 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
186 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
187 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
188 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
189 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
190 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
191 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
192 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
193 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
194 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
195 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
196 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
197 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
198 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
199 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
200 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
201 | github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 h1:Po+wkNdMmN+Zj1tDsJQy7mJlPlwGNQd9JZoPjObagf8=
202 | github.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49/go.mod h1:YiutDnxPRLk5DLUFj6Rw4pRBBURZY07GFr54NdV9mQg=
203 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
204 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
205 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
206 | github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e h1:LvL4XsI70QxOGHed6yhQtAU34Kx3Qq2wwBzGFKY8zKk=
207 | github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
208 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
209 | github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
210 | github.com/jung-kurt/gofpdf v1.16.2 h1:jgbatWHfRlPYiK85qgevsZTHviWXKwB1TTiKdz5PtRc=
211 | github.com/jung-kurt/gofpdf v1.16.2/go.mod h1:1hl7y57EsiPAkLbOwzpzqgx1A30nQCk/YmFV8S2vmK0=
212 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
213 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
214 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
215 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
216 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
217 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
218 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
219 | github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
220 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
221 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
222 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
223 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
224 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
225 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
226 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
227 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
228 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
229 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
230 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
231 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
232 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
233 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
234 | github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
235 | github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
236 | github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
237 | github.com/nicksnyder/go-i18n/v2 v2.4.0/go.mod h1:nxYSZE9M0bf3Y70gPQjN9ha7XNHX7gMc814+6wVyEI4=
238 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
239 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
240 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
241 | github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
242 | github.com/phpdave11/gofpdi v1.0.7/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
243 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
244 | github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
245 | github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDjvNo=
246 | github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
247 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
248 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
249 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
250 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
251 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
252 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
253 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
254 | github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
255 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
256 | github.com/rymdport/portal v0.2.6 h1:HWmU3gORu7vWcpr7VSwUS2Xx1HtJXVcUuTqEZcMEsIg=
257 | github.com/rymdport/portal v0.2.6/go.mod h1:kFF4jslnJ8pD5uCi17brj/ODlfIidOxlgUDTO5ncnC4=
258 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
259 | github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
260 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
261 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
262 | github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
263 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
264 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
265 | github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
266 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
267 | github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
268 | github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
269 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
270 | github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
271 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE=
272 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q=
273 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ=
274 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE=
275 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
276 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
277 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
278 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
279 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
280 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
281 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
282 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
283 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
284 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
285 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
286 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
287 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
288 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
289 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
290 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
291 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
292 | github.com/yuin/goldmark v1.7.1 h1:3bajkSilaCbjdKVsKdZjZCLBNPL9pYzrCakKaf4U49U=
293 | github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
294 | go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
295 | go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
296 | go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
297 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
298 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
299 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
300 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
301 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
302 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
303 | go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
304 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
305 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
306 | go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
307 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
308 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
309 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
310 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
311 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
312 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
313 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
314 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
315 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
316 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
317 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
318 | golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
319 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
320 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
321 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
322 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
323 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
324 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
325 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
326 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
327 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
328 | golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
329 | golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
330 | golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
331 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
332 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
333 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
334 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
335 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
336 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
337 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
338 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
339 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
340 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
341 | golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
342 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
343 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
344 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
345 | golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ=
346 | golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a h1:sYbmY3FwUWCBTodZL1S3JUuOvaW6kM2o+clDzzDNBWg=
347 | golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a/go.mod h1:Ede7gF0KGoHlj822RtphAHK1jLdrcuRBZg0sF1Q+SPc=
348 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
349 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
350 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
351 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
352 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
353 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
354 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
355 | golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
356 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
357 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
358 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
359 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
360 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
361 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
362 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
363 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
364 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
365 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
366 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
367 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
368 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
369 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
370 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
371 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
372 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
373 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
374 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
375 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
376 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
377 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
378 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
379 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
380 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
381 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
382 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
383 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
384 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
385 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
386 | golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
387 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
388 | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
389 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
390 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
391 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
392 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
393 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
394 | golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
395 | golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
396 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
397 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
398 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
399 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
400 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
401 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
402 | golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
403 | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
404 | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
405 | golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
406 | golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
407 | golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
408 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
409 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
410 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
411 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
412 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
413 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
414 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
415 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
416 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
417 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
418 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
419 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
420 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
421 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
422 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
423 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
424 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
425 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
426 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
427 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
428 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
429 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
430 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
431 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
432 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
433 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
434 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
435 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
436 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
437 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
438 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
439 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
440 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
441 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
442 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
443 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
444 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
445 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
446 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
447 | golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
448 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
449 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
450 | golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
451 | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
452 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
453 | golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
454 | golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
455 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
456 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
457 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
458 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
459 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
460 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
461 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
462 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
463 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
464 | golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
465 | golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
466 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
467 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
468 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
469 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
470 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
471 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
472 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
473 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
474 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
475 | golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
476 | golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
477 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
478 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
479 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
480 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
481 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
482 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
483 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
484 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
485 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
486 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
487 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
488 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
489 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
490 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
491 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
492 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
493 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
494 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
495 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
496 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
497 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
498 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
499 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
500 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
501 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
502 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
503 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
504 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
505 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
506 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
507 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
508 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
509 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
510 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
511 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
512 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
513 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
514 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
515 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
516 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
517 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
518 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
519 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
520 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
521 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
522 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
523 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
524 | golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
525 | golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
526 | golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
527 | golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
528 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
529 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
530 | golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
531 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
532 | golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
533 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
534 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
535 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
536 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
537 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
538 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
539 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
540 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
541 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
542 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
543 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
544 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
545 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
546 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
547 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
548 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
549 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
550 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
551 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
552 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
553 | google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
554 | google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
555 | google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
556 | google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
557 | google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
558 | google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
559 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
560 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
561 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
562 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
563 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
564 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
565 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
566 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
567 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
568 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
569 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
570 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
571 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
572 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
573 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
574 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
575 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
576 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
577 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
578 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
579 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
580 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
581 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
582 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
583 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
584 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
585 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
586 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
587 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
588 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
589 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
590 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
591 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
592 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
593 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
594 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
595 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
596 | google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
597 | google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
598 | google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
599 | google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
600 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
601 | google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
602 | google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
603 | google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
604 | google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
605 | google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
606 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
607 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
608 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
609 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
610 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
611 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
612 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
613 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
614 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
615 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
616 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
617 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
618 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
619 | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
620 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
621 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
622 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
623 | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
624 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
625 | google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
626 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
627 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
628 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
629 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
630 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
631 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
632 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
633 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
634 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
635 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
636 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
637 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
638 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
639 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
640 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
641 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
642 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
643 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
644 | gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
645 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
646 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
647 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
648 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
649 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
650 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
651 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
652 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
653 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
654 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
655 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
656 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
657 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
658 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
659 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
660 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
661 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
662 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
663 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
664 |
--------------------------------------------------------------------------------