-
Notifications
You must be signed in to change notification settings - Fork 740
feat: verbose output utility for policy builder #5502
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@@ -1,4 +1,4 @@ | |||
name: ELBSecurityPolicy-2016-08 | |||
name: ELBSecurityPolicy-TLS-1-0-2015-05 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this seems confusing, it's expected behavior because the tool searches the security_policy_selection
array to find the first matching policy object. Although the names are different, they both point to the same exact policy configuration.
This might be confusing, but I don't think it will be an issue for someone trying to understand the components of the security policy. I considered two alternatives:
-
List all aliases: Show all policy names that map to the same policy object. This would be useful for identifying equivalent policies but comes with a performance cost.
-
Retain the user's input: Store whatever the user requested initially when building the policy builder and use that value for the name. This would require adding a new field to the
s2n_security_policy_builder
struct, but since we don't have other use cases for that field, I'm not sure if we want to commit to it yet.
I'd appreciate any opinions on this.
* FORMAT_V1: Human-readable YAML-style format | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really YAML? If it is, it's a coincidence 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're claiming this is YAML should we try to parse the results with a YAML parser maybe?
* @param fd The file descriptor to write to (e.g., STDOUT_FILENO or an open file) | ||
* @returns S2N_SUCCESS on success, S2N_FAILURE on failure | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think writing to a file descriptor is sufficient? Would customers want to write to memory instead? This might be particularly important bc I don't believe any of our current APIs write to a file descriptor yet.
/* Future formats can be added here */ | ||
} s2n_policy_format; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Idk about this placeholder comment in what will eventually be a public enum
* - rules: | ||
* - <rule_name>: <yes|no> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would true/false be more normal, if we're calling this YAML?
int s2n_policy_builder_write_verbose(struct s2n_security_policy_builder *builder, | ||
s2n_policy_format format, int fd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be operating on the s2n_security_policy itself, not the builder. We want to print the actual policies, and we want it to be applicable to policies regardless of origin.
/* TODO: Currently outputs the base_policy. This needs to be updated once builder implements a "finalized" policy field */ | ||
const char *policy_name = "unknown"; | ||
for (size_t i = 0; security_policy_selection[i].version != NULL; i++) { | ||
if (security_policy_selection[i].security_policy == builder->base_policy) { | ||
policy_name = security_policy_selection[i].version; | ||
break; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal here isn't to print existing, hard-coded policies (except to share code with bin/policy.c). The goal is to print the newly constructed policies, to see the results of the builder. That means you cannot rely on security_policy_selection. The new policy won't be in security_policy_selection.
* - kem groups: | ||
* -- <kem_group_name> | ||
*/ | ||
S2N_POLICY_FORMAT_V1 = 1, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of version numbers for the policy formats? Is the thought that we can't update our format at all because we might break users? Does that mean we'll potentially have two very similar YAML outputs if we want to make a minor change to V1?
In this case I wonder if it'd be worth giving the formats a name in addition to the version? Like
S2N_POLICY_FORMAT_YAML_V1 = 1,
S2N_POLICY_FORMAT_YAML_V2 = 2,
S2N_POLICY_FORMAT_XML_V1 = 3,
Otherwise it might be strange to have V1 be YAML, V2 be some completely other thing, and V3 be a slight modification to the V1 YAML?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if policy_builder is the right place for this stuff. It seems like it might pollute the actual security policy builder logic if we add a bunch of new output formats? Maybe s2n_policy_writer.c
or something? Not sure.
|
||
POSIX_GUARD(s2n_write_fd_formatted(fd, "name: %s\n", policy_name)); | ||
|
||
const char *version_str = version_strs[policy->minimum_protocol_version]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to check that policy->minimum_protocol_version
isn't too large for version_strs
. Though unlikely, I could see special values being used to mean "any version" or something, and we wouldn't want to over-read version_strs
.
} | ||
|
||
/* Write verbose policy output in FORMAT_V1 style */ | ||
static int s2n_policy_write_format_v1(const struct s2n_security_policy *policy, const char *policy_name, int fd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally internal functions would return S2N_RESULT. See
Line 19 in 792d366
* The goal of s2n_result is to provide a strongly-typed error |
* FORMAT_V1: Human-readable YAML-style format | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're claiming this is YAML should we try to parse the results with a YAML parser maybe?
RESULT_ENSURE(buffer_size > 0, S2N_ERR_INVALID_ARGUMENT); | ||
|
||
/* Use a pipe for capturing output */ | ||
int pipe_fds[2]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compiler might not initialize your variables for you, so it's best to do it manually. Having your variables initialized with garbage can lead to undefined behavior.
int pipe_fds[2]; | |
int pipe_fds[2] = { 0 }; |
Release Summary:
Resolved issues:
Description of changes:
Adds a utility function to the policy builder for outputting a breakdown of a security policy. We define a
V1
format that we currently use for the policy snapshot utility, and replace it to use this policy builder utility instead. I essentially moved the bin/policy.c utility into the policy builder. In the long term, we plan to add more formalized formats which we can add asV2
,V3
, etc .Call-outs:
I ran the following command to regenerate all the snapshots and verify that the new policy output utility is working:
As a result, some snapshots were updated.
Testing:
Added unit tests for happy paths as well as negative paths. We have snapshot test that checks for exact content match.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.