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

Add period and max_ttl to cert role creation #3642

Merged
merged 19 commits into from
Dec 18, 2017
Merged

Conversation

calvn
Copy link
Contributor

@calvn calvn commented Dec 3, 2017

Closes #3533

@calvn calvn requested review from jefferai and vishalnayak December 3, 2017 21:25
return &logical.Response{
Data: map[string]interface{}{
"certificate": cert.Certificate,
"display_name": cert.DisplayName,
"policies": cert.Policies,
"ttl": duration / time.Second,
Copy link
Member

Choose a reason for hiding this comment

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

I think we should actually not display ttl, max_ttl, or period if they're not set. This is because the value will vary according to the system/mount tuning, so returning 0 (or not returning the key at all) keeps people from making assumptions based on snapshots of the current values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Period will be 0 if that's not set. I can remove ttl and max_ttl from using the sys values if those are zero so that they return zero as well. AFAIK the other backends return ttl, max_ttl, and period all the time so if we do decide to remove them if unset we would have to do so for other backends as well, though this would could be a breaking change on people using these values from the response.

If this value will vary and we are returning 0 or hiding it if it's unset, where can the user/operator find out what these values are, would it be by doing a token lookup directly?

if ttl == 0 {
ttl = time.Second * time.Duration(d.Get("lease").(int))
}
if ttl > systemDefaultTTL {
Copy link
Member

Choose a reason for hiding this comment

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

Don't check against system TTL/max TTL. We'll automatically truncate the time for issued credentials and this can cause subtle issues. At the most, I'd make this a warning instead of an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've changed it to be a warning instead of error below.

if maxTTL != 0 {
// If ttl is 0, set the ttl as the max ttl
if ttl == 0 {
ttl = maxTTL
Copy link
Member

Choose a reason for hiding this comment

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

Don't do this; this will happen automatically in core if TTL is zero and there is a max TTL.


// If a period is provided, use that as the ttl instead, ignoring previously set ttl
if period > 0 {
ttl = period
Copy link
Member

Choose a reason for hiding this comment

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

Also don't do this. Set according to period at token issue or renew time. Don't modify the input parameters.

@@ -77,16 +78,21 @@ func (b *backend) pathLogin(
ttl = b.System().DefaultLeaseTTL()
}

maxTTL := matched.Entry.MaxTTL
if maxTTL == 0 {
maxTTL = b.System().MaxLeaseTTL()
Copy link
Member

Choose a reason for hiding this comment

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

You don't need to do this, the max TTL at the mount/system level will be applied automatically. However, what you do need to do is check if maxTTL is zero, and if it isn't, ensure that the TTL value is capped to it.

Basically: if both are zero, leave it at zero. If both exist, ensure that the TTL is less than the MaxTTL. If only TTL exists, leave things alone, and if only max TTL exists, set TTL to the system default and then cap it to max TTL if max TTL is less.

resp := &logical.Response{
Auth: &logical.Auth{
Period: matched.Entry.Period,
Copy link
Member

Choose a reason for hiding this comment

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

This actually isn't handled automatically (possibly/probably it should) -- if a period is non-zero, you should explicitly set the TTL to the period after the other TTL machinations are in place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is handled explicitly below now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No longer handled explicitly at the backend level, check is now performed in core after #3677

@vishalnayak
Copy link
Contributor

@calvn I don't have any new comments on top of Jeff's comments. This is looking good.

@calvn
Copy link
Contributor Author

calvn commented Dec 11, 2017

@jefferai this should be good for a second look

@jefferai jefferai added this to the 0.9.1 milestone Dec 14, 2017
duration = b.System().DefaultLeaseTTL()
ttl := cert.TTL
if ttl == 0 {
ttl = b.System().DefaultLeaseTTL()
Copy link
Member

Choose a reason for hiding this comment

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

When returning the cert info we should return the actual stored info, not the effective info. Let the cert.TTL and cert.MaxTTL bits stay at zero if they're zero, because that indicates that they weren't configured.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Yes.

resp.AddWarning(fmt.Sprintf("Given max_ttl of %d seconds is greater than current mount/system default of %d seconds", maxTTL/time.Second, systemMaxTTL/time.Second))
}

if maxTTL < time.Duration(0) {
Copy link
Member

Choose a reason for hiding this comment

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

Should probably have a similar check for ttl

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Handled up top as well now

// Parse period
period := time.Duration(d.Get("period").(int)) * time.Second
if period > systemMaxTTL {
return logical.ErrorResponse(fmt.Sprintf("Given period of %d seconds is greater than the backend's maximum TTL of %d seconds", period/time.Second, systemMaxTTL/time.Second)), nil
Copy link
Member

Choose a reason for hiding this comment

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

This should be a warning, not an error.

@@ -79,14 +80,14 @@ func (b *backend) pathLogin(

clientCerts := req.Connection.ConnState.PeerCertificates
if len(clientCerts) == 0 {
return logical.ErrorResponse("no client certificate found"), nil
return nil, fmt.Errorf("no client certificate found")
Copy link
Member

Choose a reason for hiding this comment

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

Why change this? This is more likely to be user error than an internal error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -135,7 +152,7 @@ func (b *backend) pathLoginRenew(

clientCerts := req.Connection.ConnState.PeerCertificates
if len(clientCerts) == 0 {
return nil, fmt.Errorf("no client certificate found")
return logical.ErrorResponse("no client certificate found"), nil
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need a typed error return, maybe logical.ErrInvalidRequest?

Copy link
Member

Choose a reason for hiding this comment

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

ErrInvalidRequest is actually the default for a logical.ErrorResponse with no typed error.

Copy link
Contributor

Choose a reason for hiding this comment

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

Good to know!

(`3600`) or an integer time unit (`60m`) after which the issued token can no
longer be renewed.
- `period` `(string: "")` - Duration in either an integer number of seconds
(3600) or an integer time unit (60m). If set, the generated token is a
Copy link
Contributor

Choose a reason for hiding this comment

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

Integer time unit is not used anywhere else in the docs and is a little confusing. I've seen a duration with hours as the largest suffix as well as some other ones. We should probably make the docs consistent for ttl, max_ttl, and period.

systemDefaultTTL := b.System().DefaultLeaseTTL()
ttl := time.Duration(d.Get("ttl").(int)) * time.Second
if ttl == 0 {
ttl = time.Second * time.Duration(d.Get("lease").(int))
Copy link
Contributor

Choose a reason for hiding this comment

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

minor, the previous statement is ttl * time.Second while this one is time.Second * lease.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should definitely be ttl, nice catch!

Copy link
Contributor

Choose a reason for hiding this comment

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

That is for backwards compatibility with the old term for it, lease. I was just commenting on the ordering of the time math which makes it harder to scan through.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea you're right. I'll swap the ordering and keep lease.

chrishoffman
chrishoffman previously approved these changes Dec 18, 2017
Copy link
Contributor

@chrishoffman chrishoffman left a comment

Choose a reason for hiding this comment

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

A few minor comments, otherwise looks good!

briankassouf
briankassouf previously approved these changes Dec 18, 2017
Copy link
Contributor

@briankassouf briankassouf left a comment

Choose a reason for hiding this comment

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

👍 , looks good!

@calvn calvn dismissed stale reviews from briankassouf and chrishoffman via 8620a95 December 18, 2017 19:29
@jefferai jefferai merged commit 40b8314 into master Dec 18, 2017
@calvn calvn deleted the tls-auth-periodic-tokens branch February 12, 2018 05:05
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.

5 participants