mirror of https://github.com/minio/minio.git
Compare commits
7 Commits
80c37f52a8
...
64c99ec2ce
Author | SHA1 | Date |
---|---|---|
|
64c99ec2ce | |
|
534f4a9fb1 | |
|
902adf1599 | |
|
4ab0449a35 | |
|
a0f7fdce4d | |
|
5d16e2b4bc | |
|
5666a30fb0 |
|
@ -106,16 +106,14 @@ func (p *scannerMetrics) log(s scannerMetric, paths ...string) func(custom map[s
|
|||
|
||||
// time n scanner actions.
|
||||
// Use for s < scannerMetricLastRealtime
|
||||
func (p *scannerMetrics) timeN(s scannerMetric) func(n int) func() {
|
||||
func (p *scannerMetrics) timeN(s scannerMetric) func(n int) {
|
||||
startTime := time.Now()
|
||||
return func(n int) func() {
|
||||
return func() {
|
||||
duration := time.Since(startTime)
|
||||
return func(n int) {
|
||||
duration := time.Since(startTime)
|
||||
|
||||
atomic.AddUint64(&p.operations[s], uint64(n))
|
||||
if s < scannerMetricLastRealtime {
|
||||
p.latency[s].add(duration)
|
||||
}
|
||||
atomic.AddUint64(&p.operations[s], uint64(n))
|
||||
if s < scannerMetricLastRealtime {
|
||||
p.latency[s].add(duration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -783,6 +783,24 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
|
|||
writeSuccessResponseXML(w, encodedSuccessResponse)
|
||||
}
|
||||
|
||||
func extractPolicyName(sanURI string) (string, error) {
|
||||
|
||||
parsedURL, err := url.Parse(sanURI)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
key := parsedURL.Host + strings.ReplaceAll(parsedURL.Path, "/", "+")
|
||||
|
||||
if len(key) > 128 {
|
||||
return "", errors.New("Policy URL " + key + " is more than 128 characters long.")
|
||||
}
|
||||
|
||||
return key, nil
|
||||
|
||||
}
|
||||
|
||||
// AssumeRoleWithCertificate implements user authentication with client certificates.
|
||||
// It verifies the client-provided X.509 certificate, maps the certificate to an S3 policy
|
||||
// and returns temp. S3 credentials to the client.
|
||||
|
@ -893,15 +911,44 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
|||
}
|
||||
}
|
||||
|
||||
// We map the X.509 subject common name to the policy. So, a client
|
||||
// with the common name "foo" will be associated with the policy "foo".
|
||||
// Other mapping functions - e.g. public-key hash based mapping - are
|
||||
// possible but not implemented.
|
||||
//
|
||||
// Group mapping is not possible with standard X.509 certificates.
|
||||
if certificate.Subject.CommonName == "" {
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, errors.New("certificate subject CN cannot be empty"))
|
||||
return
|
||||
var tlsSubKey string
|
||||
|
||||
if !globalIAMSys.STSTLSConfig.TLSSubjectUseSanURI {
|
||||
// We map the X.509 subject common name to the policy. So, a client
|
||||
// with the common name "foo" will be associated with the policy "foo".
|
||||
// Other mapping functions - e.g. public-key hash based mapping - are
|
||||
// possible but not implemented.
|
||||
//
|
||||
// Group mapping is not possible with standard X.509 certificates.
|
||||
if certificate.Subject.CommonName == "" {
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, errors.New("certificate subject CN cannot be empty"))
|
||||
return
|
||||
}
|
||||
tlsSubKey = certificate.Subject.CommonName
|
||||
} else {
|
||||
// We map the X.509 san uri to the policy. So, a client
|
||||
// with the san uri "http://myapp" will be associated with the policy "http://myapp".
|
||||
// Other mapping functions - e.g. public-key hash based mapping - are
|
||||
// possible but not implemented.
|
||||
//
|
||||
// Group mapping is not possible with standard X.509 certificates.
|
||||
if len(certificate.URIs) == 0 {
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSMissingParameter, errors.New("SAN URI not present in the certificate"))
|
||||
return
|
||||
}
|
||||
|
||||
// Pick first SAN URI
|
||||
// Extract Policy Name From SAN URI
|
||||
// Set Policy Name as Subject Key
|
||||
policyName, err := extractPolicyName(certificate.URIs[0].String())
|
||||
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, errors.New("Unable to convert from SAN URI to Policy Name"))
|
||||
return
|
||||
}
|
||||
|
||||
tlsSubKey = policyName
|
||||
|
||||
}
|
||||
|
||||
expiry, err := globalIAMSys.STSTLSConfig.GetExpiryDuration(r.Form.Get(stsDurationSeconds))
|
||||
|
@ -919,13 +966,14 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
|||
}
|
||||
|
||||
// Associate any service accounts to the certificate CN
|
||||
parentUser := "tls" + getKeySeparator() + certificate.Subject.CommonName
|
||||
parentUser := "tls" + getKeySeparator() + tlsSubKey
|
||||
|
||||
claims[expClaim] = UTCNow().Add(expiry).Unix()
|
||||
claims[subClaim] = certificate.Subject.CommonName
|
||||
claims[subClaim] = tlsSubKey
|
||||
claims[audClaim] = certificate.Subject.Organization
|
||||
claims[issClaim] = certificate.Issuer.CommonName
|
||||
claims[parentClaim] = parentUser
|
||||
|
||||
tokenRevokeType := r.Form.Get(stsRevokeTokenType)
|
||||
if tokenRevokeType != "" {
|
||||
claims[tokenRevokeTypeClaim] = tokenRevokeType
|
||||
|
@ -943,7 +991,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
|
|||
}
|
||||
|
||||
tmpCredentials.ParentUser = parentUser
|
||||
policyName := certificate.Subject.CommonName
|
||||
policyName := tlsSubKey
|
||||
updatedAt, err := globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, policyName)
|
||||
if err != nil {
|
||||
writeSTSErrorResponse(ctx, w, ErrSTSInternalError, err)
|
||||
|
|
|
@ -41,6 +41,22 @@ const (
|
|||
// clients to obtain temp. credentials with arbitrary policy
|
||||
// permissions - including admin permissions.
|
||||
EnvIdentityTLSSkipVerify = "MINIO_IDENTITY_TLS_SKIP_VERIFY"
|
||||
|
||||
// EnvIdentityTLSSubjectSanURI is an environmental variable that is used to select
|
||||
// Subject for verified certificate identity in JWT Claim.
|
||||
// This claim is sent to Authorization Engine.
|
||||
// If set to true, First URI will be used as subject instead of CommonName
|
||||
// The URI will be converted into suitable policy name by following operations
|
||||
// 1. remove protocol name (or scheme name) from URI
|
||||
// 2. Replace all Path separators (ie /) from the Path in URI, this results in CleanedPath
|
||||
// 3. Join Host+CleanedPath
|
||||
// 4. If the above string becomes greater than 128 characters in length, then
|
||||
// a proper error is thrown
|
||||
// As example, http://my.domain:10000/my/app/path will be converted to
|
||||
// my.domain:10000+my+app+path
|
||||
// Valid values for this field are true and false
|
||||
// By default, it will be false. Thus Common Name will be used
|
||||
EnvIdentityTLSSubjectSanURI = "MINIO_IDENTITY_TLS_SUBJECT_USE_SANURI"
|
||||
)
|
||||
|
||||
// Config contains the STS TLS configuration for generating temp.
|
||||
|
@ -52,6 +68,11 @@ type Config struct {
|
|||
// certificate verification. It should only be set for
|
||||
// debugging or testing purposes.
|
||||
InsecureSkipVerify bool `json:"skip_verify"`
|
||||
|
||||
// TLSSubjectUseSANUri, if set to true, uses first SAN URI from
|
||||
// the client certificate as subject. This is done instead of
|
||||
// using Common Name.
|
||||
TLSSubjectUseSanURI bool `json:"use_san_uri"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -99,11 +120,18 @@ func Lookup(kvs config.KVS) (Config, error) {
|
|||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
cfg.TLSSubjectUseSanURI, err = config.ParseBool(env.Get(EnvIdentityTLSSubjectSanURI, kvs.Get(tlsSubjectUseSanURI)))
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
const (
|
||||
skipVerify = "skip_verify"
|
||||
skipVerify = "skip_verify"
|
||||
tlsSubjectUseSanURI = "tls_subject_use_san_uri"
|
||||
)
|
||||
|
||||
// DefaultKVS is the default K/V config system for
|
||||
|
@ -113,6 +141,10 @@ var DefaultKVS = config.KVS{
|
|||
Key: skipVerify,
|
||||
Value: "off",
|
||||
},
|
||||
config.KV{
|
||||
Key: tlsSubjectUseSanURI,
|
||||
Value: "off",
|
||||
},
|
||||
}
|
||||
|
||||
// Help is the help and description for the STS API K/V configuration.
|
||||
|
@ -123,4 +155,10 @@ var Help = config.HelpKVS{
|
|||
Optional: true,
|
||||
Type: "on|off",
|
||||
},
|
||||
config.HelpKV{
|
||||
Key: tlsSubjectUseSanURI,
|
||||
Description: `use cleaned value of first san uri from client certificate instead common name. cleaning results in stripping scheme, replacing path separator with plus sign in uri path and joining it with host name (default: 'off')`,
|
||||
Optional: true,
|
||||
Type: "on|off",
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue