mirror of
https://github.com/gravitational/teleport
synced 2024-10-22 02:03:24 +00:00
Add signing constraints
This commit is contained in:
parent
791c55548d
commit
e513a789c5
|
@ -212,9 +212,9 @@ func (s *AuthServer) GenerateHostCert(key []byte, hostID, authDomain string, rol
|
|||
|
||||
// GenerateUserCert generates user certificate, it takes pkey as a signing
|
||||
// private key (user certificate authority)
|
||||
func (s *AuthServer) GenerateUserCert(
|
||||
key []byte, username string, ttl time.Duration) ([]byte, error) {
|
||||
|
||||
func (s *AuthServer) GenerateUserCert(key []byte, username string, allowedLogins []string, ttl time.Duration) ([]byte, error) {
|
||||
// here I should map username to appropriate certificate authority
|
||||
// how do I do that?
|
||||
ca, err := s.Trust.GetCertAuthority(services.CertAuthID{
|
||||
Type: services.UserCA,
|
||||
DomainName: s.DomainName,
|
||||
|
@ -226,11 +226,7 @@ func (s *AuthServer) GenerateUserCert(
|
|||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
user, err := s.GetUser(username)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return s.Authority.GenerateUserCert(privateKey, key, username, user.GetAllowedLogins(), ttl)
|
||||
return s.Authority.GenerateUserCert(privateKey, key, username, allowedLogins, ttl)
|
||||
}
|
||||
|
||||
func (s *AuthServer) SignIn(user string, password []byte) (*Session, error) {
|
||||
|
|
|
@ -348,7 +348,12 @@ func (a *AuthWithRoles) GenerateUserCert(key []byte, user string, ttl time.Durat
|
|||
if err := a.currentUserAction(user); err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return a.authServer.GenerateUserCert(key, user, ttl)
|
||||
// check signing TTL and return a list of allowed logins
|
||||
allowedLogins, err := a.checker.CheckLogins(ttl)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
return a.authServer.GenerateUserCert(key, user, allowedLogins, ttl)
|
||||
}
|
||||
|
||||
func (a *AuthWithRoles) CreateSignupToken(user services.User) (token string, e error) {
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"github.com/gravitational/teleport/lib/utils"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/gravitational/configure/cstrings"
|
||||
"github.com/gravitational/trace"
|
||||
)
|
||||
|
||||
|
@ -112,6 +113,14 @@ func (r *RoleResource) CheckAndSetDefaults() error {
|
|||
if r.Spec.MaxSessionTTL.Duration < defaults.MinCertDuration {
|
||||
return trace.BadParameter("maximum session TTL can not be less than")
|
||||
}
|
||||
for _, login := range r.Spec.Logins {
|
||||
if login == Wildcard {
|
||||
return trace.BadParameter("wilcard matcher is not allowed in logins")
|
||||
}
|
||||
if !cstrings.IsValidUnixUser(login) {
|
||||
return trace.BadParameter("'%v' is not a valid user name", login)
|
||||
}
|
||||
}
|
||||
for key, val := range r.Spec.NodeLabels {
|
||||
if key == Wildcard && val != Wildcard {
|
||||
return trace.BadParameter("selector *:<val> is not supported")
|
||||
|
@ -141,6 +150,9 @@ type AccessChecker interface {
|
|||
CheckAccessToServer(login string, server Server) error
|
||||
// CheckResourceAction check access to resource action
|
||||
CheckResourceAction(resourceNamespace, resourceName, accessType string) error
|
||||
// CheckLogins checks if role set can login up to given duration
|
||||
// and returns a combined list of allowed logins
|
||||
CheckLogins(ttl time.Duration) ([]string, error)
|
||||
}
|
||||
|
||||
// FromSpec returns new RoleSet created from spec
|
||||
|
@ -213,7 +225,7 @@ func MatchResourceAction(selector map[string][]string, resourceName, resourceAct
|
|||
// MatchLogin returns true if attempted login matches any of the logins
|
||||
func MatchLogin(logins []string, login string) bool {
|
||||
for _, l := range logins {
|
||||
if l == login || l == Wildcard {
|
||||
if l == login {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -249,6 +261,32 @@ func MatchLabels(selector map[string]string, target map[string]string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// CheckLogins checks if role set can login up to given duration
|
||||
// and returns a combined list of allowed logins
|
||||
func (set RoleSet) CheckLogins(ttl time.Duration) ([]string, error) {
|
||||
var logins map[string]bool
|
||||
var matchedTTL bool
|
||||
for _, role := range set {
|
||||
if ttl < role.GetMaxSessionTTL().Duration {
|
||||
matchedTTL = true
|
||||
}
|
||||
for _, login := range role.GetLogins() {
|
||||
logins[login] = true
|
||||
}
|
||||
}
|
||||
if !matchedTTL {
|
||||
return nil, trace.AccessDenied("this user can not sign certificate for %v", ttl)
|
||||
}
|
||||
if len(logins) == 0 {
|
||||
return nil, trace.AccessDenied("this user can not create SSH sessions, has no logins")
|
||||
}
|
||||
out := make([]string, 0, len(logins))
|
||||
for login := range logins {
|
||||
out = append(out, login)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// CheckAccessToServer checks if role set has access to server based
|
||||
// on combined role's selector and attempted login
|
||||
func (set RoleSet) CheckAccessToServer(login string, s Server) error {
|
||||
|
|
Loading…
Reference in a new issue