-
-
Notifications
You must be signed in to change notification settings - Fork 293
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
Add TOS checker #165
Add TOS checker #165
Conversation
Signed-off-by: Cristian Le <[email protected]>
…improved the CheckAccountTOS
Thanks for the PR! I'm swamped with a few things this week including getting married but I'll try to circle back to this soon! |
Oh, congratulations! Take your time :). The latest commit has all of the refactoring I had in mind, so as long as I am not overlooking some interactions, it should be fine to add if you agree to add this interface. |
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.
Thanks for this contribution; just remembered I started reviewing this and didn't finish my first pass of it due to being sick. I'm catching up on things but here's a couple notes to get you started.
} else { | ||
// can't prompt a user who isn't there; they should | ||
// have reviewed the terms beforehand | ||
am.Agreed = true |
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 worry that removing this could break some important behavior. Are you sure the new CheckAccountTOS()
preserves this?
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.
According to my GoLand, newAcmeClientWithAccount
was only used in doIssue
and revoke
. I have added the necessary checks for those in lines in acmemanager.go
lines 336-338 and 454-456. And since it's a private function, it should cover all usecases as far as I understand golang.
As for the logic, the only change is that client.account.TermsOfServiceAgreed
is no longer taken to be agreed by default, but instead use whatever the accountmanager
option is set to (default is false
if I understand correctly). I believe this is a safer choice so that the application manages if there are implicit TOS acceptance or not.
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.
In the past we've been bitten in major ways by being less careful with this logic; I think we should leave this unchanged unless there's a specific case that is breaking with this here.
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.
About not doing the proposed change, here is the workaround I had to do without it. It is messy to say the least.
However I think it is better if this actually breaks, because it only happens if the user did not accept the TOS, i.e. the current method assumes that the TOS is accepted regardless (hence the need for this PR). Yes, we do need to check the other testers and add CheckAccountTOS
call beforehand to make sure they are automated properly. If you can point me to some of the potential places where it needs I can add appropriate test. Also can we add something like step_ca
to the go tests to automate all the necessary tests?
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.
Should the CheckAccountTOS()
method check to make sure the current version of the ToS have been agreed to? Since that can change, and might require re-agreement if updated.
if !client.account.TermsOfServiceAgreed { | ||
return nil, false, fmt.Errorf("user must agree to CA terms") | ||
} |
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 think the CA should enforce this, not the client.
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 there a standard for the CA to check/enforce the TOS? How do we communicate with the CA to confirm that the client is accepting TOS?
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 CA can choose to enforce this if that's important to them -- the CA sends the TOS link in the directory, and we send a boolean value during ACME to indicate whether client has agreed or not.
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.
It's been a while I kinda lost track of this. The main idea here was that the URL/hash of the TOS should be shaved locally as a cache, and if the TOS is not agreed send it to the CA as not agreed? Isn't it equivalent to error-out there and ask the user to accept manually? You are considering that the CA would have special behaviour that allow to be used when new TOS is not accepted? But the user should be informed, so I think it is more reasonable to require the user to explicitly accept/decline the new TOS.
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 the TOS have changed, then the CA will return an error to the ACME client.
} else { | ||
// can't prompt a user who isn't there; they should | ||
// have reviewed the terms beforehand | ||
am.Agreed = true |
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.
In the past we've been bitten in major ways by being less careful with this logic; I think we should leave this unchanged unless there's a specific case that is breaking with this here.
I think I'd be more comfortable accepting this change if the only change was adding |
I have lost track of this one, do you want to take over this one, or should I come back to it in a few weeks after I get caught up on it. |
Yeah, sorry about dropping the ball on this one. Based on my understanding, I think we can close this, since the CA server will notify client if there is a change and new ToS needs to be accepted. |
I think there was something relevant to gitea in order to make the process more explicit. Iirc in the version that was there, the TOS was automatically accepted without the user's explicit consent if it was run in non-interactive mode, which I wanted to fix in this PR |
You mean in gitea's non-interactive mode? |
I believe I had to make the portion of gitea related to acme be non-interactive because I did not know of a way to make that an interactive process. |
So to make sure I understand, the change you're proposing would force noninteractive environments to become interactive? |
Yes, I think this was so that gitea does not wait for any response that it would not have been able to handle. The current version was always accepting, but instead the PR was trying to check the current configuration first, and if the TOS was not accepted (or different) it should fail instead of wait for interactive response. |
I don't think we can reliably fail in non-interactive mode, that would take sites offline. |
You mean like when this is run while the site is in production 🤔. Isn't that a legally safe option despite being inconvenient, but I understand the difficulty of balancing. I don't think just throwing errors would be helpful because the admin might just ignore it. Maybe exposing this as a configurable option? This might not be an issue for LE, but for some random enterprise CA 🤔? |
Ok, but I think we can't allow an external factor to take a site offline without consent. Maybe there could be an option for the admin to require manually approving ToS changes. Sorry if this is disappointing after so long (my bad for leaving this PR hanging) -- I'll close it now though, maybe we can discuss an alternative approach in an issue. |
Here's a sketch of a TOS checker that would close #164.
There might be missing locks and other standards, so let me know what needs to be changed, or directly edit them.
For my usecase in gitea it seems to be doing what I intended to do.
A few changes I want to discuss:
newACMEClientWithAccount
optionally depend on it, e.g. as part ofNewAccountFunc
? The reasoning is thatinteractive == false
is the same asTermsOfServiceAgreed == true
. It's rather inelegant to have it like such.bool, string, error
(TOS_Agreed, TOS_URL, error
) to more easily distinguish if it's a TOS not being accepted or read errors. It will also be useful if the user wants to check if the TOS have changed