├── 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 |
33 |

CIS Benchmark Audit Report

34 |
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 |
69 | Download PDF 70 |
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 |
222 |

CIS Benchmark Audit Report

223 |
224 |
225 | {{ .Results }} 226 |
227 |
228 | Download PDF 229 |
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 | --------------------------------------------------------------------------------