Skip to content
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

sec: Adjust flag validation for TLS. #1582

Merged
merged 6 commits into from
Jul 30, 2023
Merged

sec: Adjust flag validation for TLS. #1582

merged 6 commits into from
Jul 30, 2023

Conversation

royjacobson
Copy link
Contributor

This changes our authentication policy when using TLS:

  1. If TLS is enabled, some authentication must be used.
  2. Password authentication is allowed for client authentication.

@royjacobson royjacobson requested a review from kostasrim July 23, 2023 11:59
Copy link
Contributor

@kostasrim kostasrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, plz expand replication_test.py with the new flag combinations

src/server/protocol_client.h Show resolved Hide resolved
src/server/protocol_client.cc Show resolved Hide resolved
src/server/protocol_client.cc Show resolved Hide resolved
src/server/protocol_client.cc Show resolved Hide resolved
@royjacobson royjacobson requested a review from kostasrim July 26, 2023 08:05
src/server/protocol_client.cc Show resolved Hide resolved
src/server/protocol_client.cc Show resolved Hide resolved
src/server/protocol_client.cc Show resolved Hide resolved
src/server/protocol_client.cc Show resolved Hide resolved
src/server/protocol_client.cc Show resolved Hide resolved
src/server/protocol_client.h Show resolved Hide resolved
src/server/server_family.cc Show resolved Hide resolved
tests/dragonfly/tls_conf_test.py Show resolved Hide resolved
@kostasrim
Copy link
Contributor

So for some reason, I could not mark the whole code block and I could not suggest the changes in one comment.

Basically, in summary, for the Validate functions you can:

  1. Mark them const since they don't modify any data member
  2. Remove the boolean flag and return. When you set the bool flag to true the rest of the checks are redundant

@royjacobson
Copy link
Contributor Author

So for some reason, I could not mark the whole code block and I could not suggest the changes in one comment.

Basically, in summary, for the Validate functions you can:

1. Mark them `const` since they don't modify any data member

2. Remove the boolean flag and return. When you set the bool flag to `true` the rest of the checks are redundant

I disagree about the has_auth changes - I wrote this code in this way so it's easy to understand exactly what properties the function guarantees and to validate it works correctly. I feel that early returns make it a bit less clear (even though it's longer).

About your first point, those are free functions :)

@royjacobson royjacobson requested a review from kostasrim July 27, 2023 11:39
@kostasrim
Copy link
Contributor

kostasrim commented Jul 27, 2023

I disagree about the has_auth changes - I wrote this code in this way so it's easy to understand exactly what properties the function guarantees and to validate it works correctly. I feel that early returns make it a bit less clear (even though it's longer).

I think the opposite is true and adding this flag adds additional cognitive overhead which is not really needed. It adds unnecessary logic to the function. For example:

void ValidateClientTlsFlags() {
  if (!absl::GetFlag(FLAGS_tls_replication)) {   //1
    return;
  }
  
  bool has_auth = false;
  
  if (!absl::GetFlag(FLAGS_tls_key_file).empty()) {
    if (absl::GetFlag(FLAGS_tls_cert_file).empty()) {
       LOG(ERROR) << "tls_cert_file flag should be set";
       exit(1);
    }
    has_auth = true;                                                                //2
 }
 
 if (!absl::GetFlag(FLAGS_masterauth).empty())
   has_auth = true;                                                                //3
}
  1. First and foremost, why would I care what happens after the function if line //2 is true? Like what value does it bring for me to go over the whole function? I have all the information I need at the right spot.
  2. Let's say something happens and now I need to debug this and figure out when has_auth became true. I can put a break point to the return at the certain line and I know what happens if I don't hit it -- that is I returned earlier than the break point. Yes I can do the same with watchpoints but that's too much. Whereas with what you have now, I need to step through and follow the logic. Imagine doing this for a large call stack, yikes!

p.s. Early returns are widely accepted as logic simplification and is something a lot of the committee members like Sean Parent, Chris Di Bella really endorse and I have personally seen in their code ;)

p.s. 2 Clang-tidy has a nice check about this called readability-else-after-return

What you are doing here, is similar to this anti-pattern only at larger scope with a boolean variable instead of early returning

Feel free to ignore me, but this IMO is not more readable. Just let me know what you decide -- I will be ok with both!

@royjacobson
Copy link
Contributor Author

@kostasrim 1 - some combinations of flags (like 'key' flag without a 'cert' flag) result in exception instead of an early return. And 2, I agree about early return in general but I feel this is a better way to write security critical code like auth policies 😅. So I'd like to stick with this version

@royjacobson royjacobson merged commit 85619e0 into main Jul 30, 2023
@romange romange deleted the tls_auth_policy branch July 31, 2023 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants