blob: 9b982a03a2deaf2cbec9a76165871360797c930a [file] [edit]
/*
* Copyright 2021 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto3";
package localtoast;
option go_package = "github.com/google/localtoast/scannerlib/proto/scan_instructions_go_proto";
// Describes how the scanner should check for compliance with a given
// benchmark.
message BenchmarkScanInstructionDef {
// Either the same instructions are used for all scan types or there
// are separate instructions for instance and image scanning.
oneof instructions {
BenchmarkScanInstruction generic = 1;
ScanTypeSpecificInstruction scan_type_specific = 2;
}
}
message ScanTypeSpecificInstruction {
BenchmarkScanInstruction instance_scanning = 1;
BenchmarkScanInstruction image_scanning = 2;
}
message BenchmarkScanInstruction {
// The benchmark is compliant if at least one of the checks in
// check_alternatives passes (OR condition).
repeated CheckAlternative check_alternatives = 1;
}
message CheckAlternative {
// The CheckAlternative passes if all the checks it includes pass (AND
// condition).
repeated FileCheck file_checks = 1;
repeated SQLCheck sql_checks = 2;
}
// A check to be performed on one or more files.
message FileCheck {
reserved 8;
repeated FileSet files_to_check = 1;
oneof check_type {
ExistenceCheck existence = 2;
PermissionCheck permission = 3;
ContentCheck content = 4;
ContentEntryCheck content_entry = 5;
}
// Optional, display this instead of the autogenerated non-compliance message.
string non_compliance_msg = 6;
// Optional, display this command for showing the non-compliant files instead
// of listing them all.
string file_display_command = 7;
// Optional, can be used to make the check run several times with slightly
// different settings.
RepeatConfig repeat_config = 9;
}
message RepeatConfig {
enum RepeatType {
// Run the checks just once.
ONCE = 0;
// Run the checks for each user found in /etc/passwd, replace "$user",
// "$home", "$uid", and "$gid" with the username, home directory, etc. in
// file names and file checks.
FOR_EACH_USER = 5;
// Same as FOR_EACH_USER, but skips users that don't have login shells.
FOR_EACH_USER_WITH_LOGIN = 1;
// Same as FOR_EACH_USER_WITH_LOGIN, but only includes system users (whose
// UID is < UID_MIN).
FOR_EACH_SYSTEM_USER_WITH_LOGIN = 2;
// Run the checks for each open ipv4/ipv6 port, replace "$port" with the
// port in file names and file checks.
FOR_EACH_OPEN_IPV4_PORT = 3;
FOR_EACH_OPEN_IPV6_PORT = 4;
}
RepeatType type = 1;
// A list of substitutions to opt out from scanning. If set, substitutions
// where a given wildcard would be replaced with a given value are skipped.
// For example, if type=FOR_EACH_USER_WITH_LOGIN, wildcard=$user,
// value=shutdown, then then "shutdown" user would not be processed in the
// check.
message OptOutSubstitution {
string wildcard = 1;
string value = 2;
}
repeated OptOutSubstitution opt_out = 2;
}
message ExistenceCheck {
// At least one file specified in the FileSet should exist if true.
// No files should exist if false.
bool should_exist = 1;
}
message PermissionCheck {
// The bits from the file permissions' octal representation (flags, owner,
// group, others) that should be set and clear.
int32 set_bits = 1;
int32 clear_bits = 2;
// The bit check passes iff...
enum BitMatchCriterion {
NOT_SET = 0;
// ...both the right bits are set and cleared
BOTH_SET_AND_CLEAR = 1;
// ...either the right bits are set or cleared
EITHER_SET_OR_CLEAR = 2;
}
BitMatchCriterion bits_should_match = 3;
// The user/group that should (not) own the file.
message OwnerCheck {
string name = 1;
bool should_own = 2;
}
OwnerCheck user = 4;
OwnerCheck group = 5;
}
// Checks for the content of the file matching a predefined value.
// For .gz files, the unzipped content is checked.
message ContentCheck {
string content = 1;
}
// Checks for entries (usually lines) in the file matching a given regex.
// For .gz files, the unzipped content is checked.
message ContentEntryCheck {
// The characters to split entries by. Uses '\n' if empty.
bytes delimiter = 1;
// Compliant iff...
enum MatchType {
// ...no criterion is satisfied or the file doesn't exist.
NONE_MATCH = 0;
// ...all criteria satisfied at least once, in strict order.
ALL_MATCH_STRICT_ORDER = 1;
// ...all criteria satisfied at least once, in any order.
ALL_MATCH_ANY_ORDER = 2;
}
MatchType match_type = 2;
repeated MatchCriterion match_criteria = 3;
}
// Describes one criterion that the the content entries need to match.
message MatchCriterion {
// Base criterion: Entries matching `filter_regex` should also
// match `expected_regex`.
// Example:
// filter_regex: "PROMPT_FOR_CONFIRM=.*"
// expected_regex: "PROMPT_FOR_CONFIRM=no"
string filter_regex = 1;
string expected_regex = 2;
repeated GroupCriterion group_criteria = 3;
}
// Additional criteria that the matched regex groups should satisfy.
message GroupCriterion {
int32 group_index = 1;
enum Type {
// The group...
// ...is an integer < `comparison_value`.
LESS_THAN = 0;
// ...is an integer > `comparison_value`.
GREATER_THAN = 1;
// ...represents rwx umask at least as strict as (const) `comparison_value`.
NO_LESS_RESTRICTIVE_UMASK = 2;
// ...appears exactly once.
UNIQUE = 3;
}
Type type = 2;
// The value to compare against is...
message Today {}
oneof comparison_value {
// ...a constant integer.
int32 const = 3;
// ...the number of days since the epoch.
Today today = 4;
}
}
// Describes the files a given FileCheck should look at.
message FileSet {
// A single file.
message SingleFile {
string path = 1;
}
// Several files inside a directory.
message FilesInDir {
string dir_path = 1;
// Includes all files under the dir and subdirs if true, and only the files
// in the top dir if false.
bool recursive = 2;
// If set, includes only files.
bool files_only = 3;
// If set, includes only directories.
bool dirs_only = 4;
// If set, omits symlinks.
bool skip_symlinks = 7;
// If set, includes only the files whose name matches the regex.
string filename_regex = 5;
// A list of file paths to opt out of traversing. For directories, none of
// the files under it will be traversed either.
repeated string opt_out_path_regexes = 6;
}
// A file in the /proc/[0-9]+/ directory of a given process, or the directory
// itself.
message ProcessPath {
// Process name as it's used in the /proc/[0-9]+/stat file.
// Should not be longer than 16 characters since names are truncated in
// stat.
string proc_name = 1;
// (Optional) The filename inside the /proc/[0-9]+/ directory.
// Example: `environ` refers to the /proc/[0-9]+/environ file.
// If left empty, the check will use the /proc/[0-9]+/ directory itself.
string file_name = 2;
// (Optional) A regex for the CLI args of the process. When set, processes
// will only be matched if their /proc/[0-9]+/cmdline file contains the
// specified regex.
string cli_arg_regex = 3;
}
// Paths listed in a Unix environment variable of a user running the scanner,
// such as $PATH.
message UnixEnvVarPaths {
string var_name = 1;
// If set, includes only files.
bool files_only = 2;
// If set, includes only directories.
bool dirs_only = 3;
}
oneof file_path {
SingleFile single_file = 1;
FilesInDir files_in_dir = 2;
ProcessPath process_path = 3;
UnixEnvVarPaths unix_env_var_paths = 4;
}
}
// A check that executes a SQL query.
message SQLCheck {
enum SQLDatabase {
DB_UNSPECIFIED = 0;
DB_MYSQL = 1;
DB_CASSANDRA = 2;
DB_ELASTICSEARCH = 3;
}
SQLDatabase target_database = 1;
string query = 2;
// Compliant iff the query returns or does not return results as we expect.
bool expect_results = 3;
// Optional, display this instead of the autogenerated non-compliance message.
string non_compliance_msg = 4;
// Only needed for ElasticSearch database, perform regex match on response.
string filter_regex = 5;
}