Commit Graph
28 Commits
Author SHA1 Message Date
rosstimothy bf270a124d Allow typical parsers to optionally support dynamic values (#39765)
Provides an opt-in mechanism to allow parsers to support dynamically
resolving variables at runtime. While this defeats some of the
static compile type benefits that typical guarantees, it is required
to allow existing parsers to be converted to use typical.

The existing resource parsers allow searching for variabls by their
fully qualified path. For example, the hostname of a server may
be quiered via `resource.spec.hostname`. In order to support this
typical could use some reflection to automatically add variables
to every nested field but that would be complicated and expensive.

Instead the ParserSpec can now be configured with
`GetUnknownIdentifier`, which allows creators of the parsers to
have full control over how a dynamic variable is resolved. The
parser prevents any dynamic resolution if the value is not configured
to limit the unsafe behvior to only parsers that explicitly opt in.
2024-03-27 13:07:47 +00:00
Zac Bergquistandhorus ff9a747001 fix: typo in comment (#36032)
Signed-off-by: Zac Bergquist <zac.bergquist@goteleport.com>
Co-authored-by: horus <horus.li@gmail.com>
2023-12-27 15:04:06 +00:00
fheinecke b178b8b732 Updated Teleport codebase to AGPL3 license (#35259)
Signed-off-by: Fred Heinecke <fred.heinecke@goteleport.com>
2023-12-01 17:48:14 +00:00
Nic KlaassenandPaul Gottschling 476ebc1f54 feat: Login Rule support for email.local and regexp.replace (#29596)
* feat: Login Rule support for email.local and regexp.replace

This commit updates the `stringListMap` function to filter out values
that map to the empty string.
This is used by `email.local` and `regexp.replace` only.
The empty values were already being filtered out in
`(*TraitsTemplateExpression).Interpolate`, adding the filtering here
just makes it more convenient to call these functions in the Login Rule
parser in teleport.e where it's desirable to have the same behaviour of
`regexp.replace` filtering out values that don't match the expression.

The actual implementation and tests for the new helpers in Login Rules
is added in a buddy PR in teleport.e.

This PR also adds documentation for the new functions.

* apply docs grammar suggestions

Co-authored-by: Paul Gottschling <paul.gottschling@goteleport.com>

---------

Co-authored-by: Paul Gottschling <paul.gottschling@goteleport.com>
2023-07-25 21:56:44 +00:00
Mike Jensen 3f6e26ae07 Fuzzing test improvements (#28066)
* Remove lib/fuzz

These fuzz targets are already configured elsewhere.  oss-fuzz targets are configured in `fuzz/oss-fuzz-build.sh`

* aws_test.go: Add FuzzParseSigV4

This adds (and enables in oss-fuzz) a new fuzz test case (and seed) for aws.go's ParseSigV4

* api/types/fuzz_test.go: Add fuzzing seeds

* api/utils/aws/fuzz_test.go: Add basic seeds to get broad coverage

* api/utils/azure/fuzz_test.go: Add seeds and enable in oss-fuzz

* lib/utils/parse/fuzz_test.go: Add fuzzing seeds

* Add opensearch fuzzing to oss-fuzz

* lib/srv/db/redis/connection/fuzz_test.go: Add fuzzing seeds

* lib/kube/proxy/fuzz_test.go: Add fuzzing seeds

* lib/srv/regular/fuzz_test.go: Add Fuzzing Seeds

* lib/utils/fuzz_test.go: Add fuzzing seeds
2023-06-20 16:14:15 +00:00
Nic Klaassen 7c8c6747cd cache parsed role template expressions (#27257)
* cache parsed template expressions

* make fix-license

* only log once every 100 cache evictions

* make fix-license

* check error inside loop
2023-06-03 00:25:28 +00:00
Nic Klaassen 3a8a1b4ab9 update lib/utils/parse to leverage lib/utils/typical (#26313)
`lib/utils/typical` is a new library for building predicate parsers
based on the examples set by `lib/utils/parse` and `e/lib/loginrule`.
The commit updates `lib/utils/parse` to use the `typical` library to
implement the two parsers defined here.

This removes a lot of code in `ast.go` that was written for each
specific function to do type checking and deal with subexpressions. This
is all handled by the `typical` library now. My hope is that this will
make it much easier to add new functions in the future and to share them
with other parsers.
2023-05-25 20:27:29 +00:00
Vitor Enes f30467eee8 Allow invalid namespaces in role templates (#21551)
This commit reverts the namespace validation added in #19696.
The new namespace validation is a breaking change that resulted in users
being locked if roles contained invalid namespaces.
2023-02-09 19:14:49 +00:00
Marco André Dinis 5dcd49cff1 Fix: change var to inner scope's Testing t (#20560) 2023-01-23 18:38:59 +01:00
Marco André DinisandVitor Enes 0fed4c7e55 Return NotFound error when trait does not exist (#20412)
We were returning a trace.BadParameter, however we should return
trace.IsNotFound.
The godoc suggests that error.
The tests suggests that error, but they were only matching for type
which is the same for all the trace.XYZ errors.

Tests are now using the `trace.Is<Error>` helper method to correctly
validate the error message.

The side effect of this change is that we were receiving a lot of logs
when interpolating traits in a role.
That log is supressed when the error is NotFound.
That was not the case before this commit: the error was a BadParameter
one, so the log is written (as debug, but still a lot of noise).

Co-authored-by: Vitor Enes <vitor.duarte@goteleport.com>
2023-01-20 12:51:04 +00:00
Vitor Enes d6ffe82aaf Support multiple transformations in role templates (#19696)
Before this commit, only a single transformation like `email.local` or
`regexp.replace` was allowed in role templates.

With this commit now users can write:
- `email.local(regexp.replace(external.email, "_", "-"))`
- `regexp.replace(email.local(regexp.replace(external.email, "_", "-")), "dev", "admin")`

This commit also allows the above expressions to not contain any
variable, i.e., it allows constant expressions like
`email.local("vitor@goteleport.com")`.
2023-01-17 15:24:50 +00:00
Jakub Nyckowski 0ee91f6c37 Enable GCI linter (#17894) 2022-10-28 20:20:28 +00:00
Norbert SzeteiandZac Bergquist 0ab9716aac oss fuzz integration (#13473)
* Update api/types/fuzz_test.go
* do not fail if the file is missing
* missing go-118-fuzz-build fix

Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
2022-06-18 21:28:07 +00:00
Nic Klaassen 92137cd110 Add regexp.replace support in role templates (#7152) 2021-06-09 19:55:07 -07:00
Alexander Klizhentas f17625c1a8 Adds controls for impersonation requests. (#6009) (#6073)
Fixes #5352

```yaml
allow:
  impersonate:
    users: ['alice', 'bob']
    roles: ['*']
    where: 'contains(user.spec.traits["groups"], impersonate_role.traits)'
```

Adds "impersonator" to all X.509 and SSH client certs
issued using impersonation and does best effort to track
requests by impersonators in audit events.

Limits certs TTL to the impersonator's max session TTL.

Prevents impersonating users to recursively impersonate
other users.

Allows impersonating users to renew their own certificate,
for example to set route to cluster.

Adds missing token permission for editor role.
2021-03-19 16:04:43 -07:00
Ben Arent 09928a7f2b Cherry pick Gravitational -> GoTeleport (#4932) 2020-11-25 11:18:55 -08:00
Andrew Lytvynov 43178f34d8 Add a depth limit to RBAC expression parser (#4848)
Our current parsing code runtime grows exponentially with nested
selectors (e.g. '{{a.b.c.d.e.f}}'), mostly due to memory churn from
slice allocations. With 100,000 levels of selectors, parsing takes ~80s
on my machine.
If an attacker can submit these expressions for parsing, they can DoS
the auth server with relatively small payloads (<1MB).

All real-world expressions are <10 AST nodes deep. Add a sanity check of
1000 levels to protect against malicious inputs.

We can optimize the code later on, but it's not very useful for real
world performance.
2020-11-17 18:53:38 +00:00
Andrew Lytvynov 566b7cc457 RFD 1: user testify/require instead of testify/assert
`require` is a sister package to `assert` that terminates the test on
failure. `assert` records the failure but lets the test proceed, which
is un-intuitive.

Also update all existing tests to match.
2020-10-16 00:15:25 +00:00
Andrew Lytvynov 01516c5744 Partial revert of negative regexps in RBAC labels
This change was not backwards compatible - variable interpolation should
work in node_labels.

This commit partially reverts
https://github.com/gravitational/teleport/pull/4253 and
https://github.com/gravitational/teleport/pull/4430
2020-10-15 21:46:06 +00:00
Andrew Lytvynov 63da43245e Validate node_labels syntax at role creation time
Also improve error output and user validation.
Based on missed feedback in https://github.com/gravitational/teleport/pull/4253#pullrequestreview-499061448
2020-10-05 18:00:55 +00:00
Andrew Lytvynov 75d7fbb508 Migrate services.MatchLabels to parse.Matcher
This should be backwards-compatible plus add the {{regexp.match(...)}}
and {{regexp.not_match(...)}} functions.
2020-09-29 21:25:50 +00:00
Andrew Lytvynov 1330415d33 utils/parse: implement Matcher
Matchers use a similar syntax to Expressions, but behave differently:
- Expressions get evaluated - they interpolate some values and return a
  final string.
- Matchers check whether some string matches a value

Matchers implement the same logic as utils.SliceMatchesRegex and add 2
new functions:
- {{regexp.match("foo")}} - match input against a raw regex
- {{regexp.not_match("foo")}} - same as match, but inverts the result
2020-09-29 21:25:50 +00:00
Andrew Lytvynov bb69574e02 utils/parse: support string literal expressions
No need to handle literal expressions (e.g. without "{{foo.bar}}"
substitutions) at the higher level. Something like "foo" is a valid
expression which always returns "foo" regardless of traits.
2020-09-29 21:25:50 +00:00
Andrew Lytvynov e9b7a25d6a utils/parse: rewrite tests in the new RFD style 2020-09-29 21:25:50 +00:00
Andrew Lytvynov 617afc7e6f Fix remaining gosimple findings
List of fixed items:

```
integration/helpers.go:1279:2               gosimple  S1000: should use for range instead of for { select {} }
integration/integration_test.go:144:5       gosimple  S1009: should omit nil check; len() for nil slices is defined as zero
integration/integration_test.go:173:5       gosimple  S1009: should omit nil check; len() for nil slices is defined as zero
integration/integration_test.go:296:28      gosimple  S1019: should use make(chan error) instead
integration/integration_test.go:570:41      gosimple  S1019: should use make(chan interface{}) instead
integration/integration_test.go:685:40      gosimple  S1019: should use make(chan interface{}) instead
integration/integration_test.go:759:33      gosimple  S1019: should use make(chan string) instead
lib/auth/init_test.go:62:2                  gosimple  S1021: should merge variable declaration with assignment on next line
lib/auth/tls_test.go:1658:22                gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
lib/backend/dynamo/dynamodbbk.go:420:5      gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/dynamo/dynamodbbk.go:656:12     gosimple  S1039: unnecessary use of fmt.Sprintf
lib/backend/etcdbk/etcd.go:458:5            gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/firestore/firestorebk.go:407:5  gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/lite/lite.go:317:5              gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/lite/lite.go:336:6              gosimple  S1004: should use !bytes.Equal(value, expected.Value) instead
lib/backend/memory/memory.go:365:5          gosimple  S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/memory/memory.go:376:5          gosimple  S1004: should use !bytes.Equal(existingItem.Value, expected.Value) instead
lib/backend/test/suite.go:327:10            gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
lib/client/api.go:1410:9                    gosimple  S1003: should use strings.ContainsRune(name, ':') instead
lib/client/api.go:2355:32                   gosimple  S1019: should use make([]ForwardedPort, len(spec)) instead
lib/client/keyagent_test.go:85:2            gosimple  S1021: should merge variable declaration with assignment on next line
lib/client/player.go:54:33                  gosimple  S1019: should use make(chan int) instead
lib/config/configuration.go:1024:52         gosimple  S1019: should use make(services.CommandLabels) instead
lib/config/configuration.go:1025:44         gosimple  S1019: should use make(map[string]string) instead
lib/config/configuration.go:930:21          gosimple  S1003: should use strings.Contains(clf.Roles, defaults.RoleNode) instead
lib/config/configuration.go:931:22          gosimple  S1003: should use strings.Contains(clf.Roles, defaults.RoleAuthService) instead
lib/config/configuration.go:932:23          gosimple  S1003: should use strings.Contains(clf.Roles, defaults.RoleProxy) instead
lib/service/supervisor.go:387:2             gosimple  S1001: should use copy() instead of a loop
lib/tlsca/parsegen.go:140:9                 gosimple  S1034: assigning the result of this type assertion to a variable (switch generalKey := generalKey.(type)) could eliminate type assertions in switch cases
lib/utils/certs.go:140:9                    gosimple  S1034: assigning the result of this type assertion to a variable (switch generalKey := generalKey.(type)) could eliminate type assertions in switch cases
lib/utils/certs.go:167:40                   gosimple  S1010: should omit second index in slice, s[a:len(s)] is identical to s[a:]
lib/utils/certs.go:204:5                    gosimple  S1004: should use !bytes.Equal(certificateChain[0].SubjectKeyId, certificateChain[0].AuthorityKeyId) instead
lib/utils/parse/parse.go:116:45             gosimple  S1003: should use strings.Contains(variable, "}}") instead
lib/utils/parse/parse.go:116:6              gosimple  S1003: should use strings.Contains(variable, "{{") instead
lib/utils/socks/socks.go:192:10             gosimple  S1025: should use String() instead of fmt.Sprintf
lib/utils/socks/socks.go:199:10             gosimple  S1025: should use String() instead of fmt.Sprintf
lib/web/apiserver.go:1054:18                gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
lib/web/apiserver.go:1954:9                 gosimple  S1039: unnecessary use of fmt.Sprintf
tool/tsh/tsh.go:1193:14                     gosimple  S1024: should use time.Until instead of t.Sub(time.Now())
```
2020-05-27 19:36:38 +00:00
Alexander Klizhentas 73ecb48232 Adds support for kubernetes_users, extend interpolation (#3404) (#3418)
This commit fixes #3369, refs #3374

It adds support for kuberenetes_users section in roles,
allowing Teleport proxy to impersonate user identities.

It also extends variable interpolation syntax by adding
suffix and prefix to variables and function `email.local`:

Example:

```yaml
kind: role
version: v3
metadata:
  name: admin
spec:
  allow:
    # extract email local part from the email claim
    logins: ['{{email.local(external.email)}}']

    # impersonate a kubernetes user with IAM prefix
    kubernetes_users: ['IAM#{{external.email}}']

  # the deny section uses the identical format as the 'allow' section.
  # the deny rules always override allow rules.
  deny: {}
```

Some notes on email.local behavior:

* This is the only function supported in the template variables for now
* In case if the email.local will encounter invalid email address,
it will interpolate to empty value, will be removed from resulting
output.

Changes in impersonation behavior:

* By default, if no kubernetes_users is set, which is a majority of cases,
  user will impersonate themselves, which is the backwards-compatible behavior.

* As long as at least one `kubernetes_users` is set, the forwarder will start
  limiting the list of users allowed by the client to impersonate.

* If the users' role set does not include actual user name, it will be rejected,
  otherwise there will be no way to exclude the user from the list).

* If the `kuberentes_users` role set includes only one user
  (quite frequently that's the real intent), teleport will default to it,
  otherwise it will refuse to select.

  This will enable the use case when `kubernetes_users` has just one field to
  link the user identity with the IAM role, for example `IAM#{{external.email}}`

* Previous versions of the forwarding proxy were denying all external
impersonation headers, this commit allows 'Impesrsonate-User' and
'Impersonate-Group' header values that are allowed by role set.

* Previous versions of the forwarding proxy ignored 'Deny' section of the roles
when applied to impersonation, this commit fixes that - roles with deny
kubernetes_users and kubernetes_groups section will not allow
impersonation of those users and groups.
2020-03-07 16:32:37 -08:00
Russell Jones df9962d572 Test cleanup.
Initialize in main utils_test.go file and name test functions match
package names.
2019-09-03 13:44:20 -07:00
Russell Jones b324616208 Added support for role variables. 2017-07-24 22:06:07 +00:00