func (s *RoloServer) kubeAuthorize(a authorizer.Attributes) error { pl, err := abac.NewFromFile(s.policyFile) if err != nil { return err } return pl.Authorize(a) }
func checkAndReloadPolicyFile(policyAuthz *abac.PolicyAuthorizer, file string) { lastModifyTime := time.Now() for { func() { defer func() { if x := recover(); x != nil { glog.Errorf("APIServer panic'd on checkAndReloadPolicyFile: %s, err: %v", file, x) } }() //var info os.FileInfo info, err := os.Stat(file) if err != nil { glog.Errorf("Stat authorizationPolicyFile: %s fail, err: %v, will retry to reload later", file, err) return } if info.ModTime().After(lastModifyTime) { lastModifyTime = info.ModTime() newPolicyList, err := abac.NewFromFile(file) if err != nil { // file format not correct glog.Errorf("Stat authorizationPolicyFile: %s fail, err: %v, will retry to reload later", file, err) return } glog.Infof("authorizationPolicyFile: %s is modified, reload finished, number of policy lines change from %d to %d", file, len(*policyAuthz.PL), len(newPolicyList)) policyAuthz.Lock.Lock() *(policyAuthz.PL) = newPolicyList policyAuthz.Lock.Unlock() } }() time.Sleep(5 * time.Second) } }
// NewAuthorizerFromAuthorizationConfig returns the right sort of union of multiple authorizer.Authorizer objects // based on the authorizationMode or an error. authorizationMode should be a comma separated values // of AuthorizationModeChoices. func NewAuthorizerFromAuthorizationConfig(authorizationModes []string, config AuthorizationConfig) (authorizer.Authorizer, error) { if len(authorizationModes) == 0 { return nil, errors.New("Atleast one authorization mode should be passed") } var authorizers []authorizer.Authorizer authorizerMap := make(map[string]bool) for _, authorizationMode := range authorizationModes { if authorizerMap[authorizationMode] { return nil, fmt.Errorf("Authorization mode %s specified more than once", authorizationMode) } // Keep cases in sync with constant list above. switch authorizationMode { case ModeAlwaysAllow: authorizers = append(authorizers, NewAlwaysAllowAuthorizer()) case ModeAlwaysDeny: authorizers = append(authorizers, NewAlwaysDenyAuthorizer()) case ModeABAC: if config.PolicyFile == "" { return nil, errors.New("ABAC's authorization policy file not passed") } abacAuthorizer, err := abac.NewFromFile(config.PolicyFile) if err != nil { return nil, err } authorizers = append(authorizers, abacAuthorizer) case ModeWebhook: if config.WebhookConfigFile == "" { return nil, errors.New("Webhook's configuration file not passed") } webhookAuthorizer, err := webhook.New(config.WebhookConfigFile, config.WebhookCacheAuthorizedTTL, config.WebhookCacheUnauthorizedTTL) if err != nil { return nil, err } authorizers = append(authorizers, webhookAuthorizer) default: return nil, fmt.Errorf("Unknown authorization mode %s specified", authorizationMode) } authorizerMap[authorizationMode] = true } if !authorizerMap[ModeABAC] && config.PolicyFile != "" { return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC") } if !authorizerMap[ModeWebhook] && config.WebhookConfigFile != "" { return nil, errors.New("Cannot specify --authorization-webhook-config-file without mode Webhook") } return union.New(authorizers...), nil }
// NewAuthorizerFromAuthorizationConfig returns the right sort of union of multiple authorizer.Authorizer objects // based on the authorizationMode or an error. authorizationMode should be a comma separated values // of AuthorizationModeChoices. func NewAuthorizerFromAuthorizationConfig(authzConfig AuthorizerConfig) (authorizer.Authorizer, error) { if len(authzConfig.AuthorizationModes) == 0 { return nil, errors.New("Atleast one authorization mode should be passed") } var authorizers []authorizer.Authorizer authorizerMap := make(map[string]bool) for _, authorizationMode := range authzConfig.AuthorizationModes { if authorizerMap[authorizationMode] { return nil, fmt.Errorf("Authorization mode %s specified more than once", authorizationMode) } // Keep cases in sync with constant list above. switch authorizationMode { case ModeAlwaysAllow: authorizers = append(authorizers, NewAlwaysAllowAuthorizer()) case ModeAlwaysDeny: authorizers = append(authorizers, NewAlwaysDenyAuthorizer()) case ModeABAC: if authzConfig.AuthorizationPolicyFile == "" { return nil, errors.New("ABAC's authorization policy file not passed") } abacAuthorizer, err := abac.NewFromFile(authzConfig.AuthorizationPolicyFile) if err != nil { return nil, err } authorizers = append(authorizers, abacAuthorizer) case ModeKeystone: if authzConfig.KeystonAuthURL == "" { return nil, errors.New("Cannot use mode Keystone without specifying --experimental-keystone-url") } keystoneAuthorizer, err := keystone.NewKeystoneAuthorizer(authzConfig.KubeClient, authzConfig.KeystonAuthURL) if err != nil { return nil, err } authorizers = append(authorizers, keystoneAuthorizer) default: return nil, fmt.Errorf("Unknown authorization mode %s specified", authorizationMode) } authorizerMap[authorizationMode] = true } if !authorizerMap[ModeABAC] && authzConfig.AuthorizationPolicyFile != "" { return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC") } if !authorizerMap[ModeKeystone] && authzConfig.KeystonAuthURL != "" { return nil, errors.New("Cannot specify --experimental-keystone-url without mode Keystone") } return union.New(authorizers...), nil }
// NewAuthorizerFromAuthorizationConfig returns the right sort of authorizer.Authorizer // based on the authorizationMode xor an error. authorizationMode should be one of AuthorizationModeChoices. func NewAuthorizerFromAuthorizationConfig(authorizationMode string, authorizationPolicyFile string) (authorizer.Authorizer, error) { if authorizationPolicyFile != "" && authorizationMode != "ABAC" { return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC") } // Keep cases in sync with constant list above. switch authorizationMode { case ModeAlwaysAllow: return NewAlwaysAllowAuthorizer(), nil case ModeAlwaysDeny: return NewAlwaysDenyAuthorizer(), nil case ModeABAC: return abac.NewFromFile(authorizationPolicyFile) default: return nil, errors.New("Unknown authorization mode") } }
func newAuthorizerWithContents(t *testing.T, contents string) authorizer.Authorizer { f, err := ioutil.TempFile("", "auth_test") if err != nil { t.Fatalf("unexpected error creating policyfile: %v", err) } f.Close() defer os.Remove(f.Name()) if err := ioutil.WriteFile(f.Name(), []byte(contents), 0700); err != nil { t.Fatalf("unexpected error writing policyfile: %v", err) } pl, err := abac.NewFromFile(f.Name()) if err != nil { t.Fatalf("unexpected error creating authorizer from policyfile: %v", err) } return pl }
// NewAuthorizerFromAuthorizationConfig returns the right sort of union of multiple authorizer.Authorizer objects // based on the authorizationMode or an error. authorizationMode should be a comma separated values // of AuthorizationModeChoices. func NewAuthorizerFromAuthorizationConfig(authorizationModes []string, authorizationPolicyFile string) (authorizer.Authorizer, error) { if len(authorizationModes) == 0 { return nil, errors.New("Atleast one authorization mode should be passed") } var authorizers []authorizer.Authorizer authorizerMap := make(map[string]bool) for _, authorizationMode := range authorizationModes { if authorizerMap[authorizationMode] { return nil, fmt.Errorf("Authorization mode %s specified more than once", authorizationMode) } // Keep cases in sync with constant list above. switch authorizationMode { case ModeAlwaysAllow: authorizers = append(authorizers, NewAlwaysAllowAuthorizer()) case ModeAlwaysDeny: authorizers = append(authorizers, NewAlwaysDenyAuthorizer()) case ModeABAC: if authorizationPolicyFile == "" { return nil, errors.New("ABAC's authorization policy file not passed") } abacAuthorizer, err := abac.NewFromFile(authorizationPolicyFile) authorizerLock := &abac.PolicyAuthorizer{PL: &abacAuthorizer, Lock: &sync.RWMutex{}} go checkAndReloadPolicyFile(authorizerLock, authorizationPolicyFile) if err != nil { return nil, err } authorizers = append(authorizers, authorizerLock) default: return nil, fmt.Errorf("Unknown authorization mode %s specified", authorizationMode) } authorizerMap[authorizationMode] = true } if !authorizerMap[ModeABAC] && authorizationPolicyFile != "" { return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC") } return union.New(authorizers...), nil }