utils.go raw

   1  // Copyright (c) 2016, 2018, 2025, Oracle and/or its affiliates.  All rights reserved.
   2  // This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.
   3  
   4  package auth
   5  
   6  import (
   7  	"bytes"
   8  	"crypto/sha256"
   9  	"crypto/x509"
  10  	"fmt"
  11  	"net/http"
  12  	"net/http/httputil"
  13  	"strings"
  14  
  15  	"github.com/nrdcg/oci-go-sdk/common/v1065"
  16  )
  17  
  18  // httpGet makes a simple HTTP GET request to the given URL, expecting only "200 OK" status code.
  19  // This is basically for the Instance Metadata Service.
  20  func httpGet(dispatcher common.HTTPRequestDispatcher, url string) (body bytes.Buffer, statusCode int, err error) {
  21  	var response *http.Response
  22  	request, err := http.NewRequest(http.MethodGet, url, nil)
  23  
  24  	request.Header.Add("Authorization", "Bearer Oracle")
  25  
  26  	if response, err = dispatcher.Do(request); err != nil {
  27  		return
  28  	}
  29  
  30  	statusCode = response.StatusCode
  31  	common.IfDebug(func() {
  32  		if dump, e := httputil.DumpResponse(response, true); e == nil {
  33  			common.Logf("Dump Response %v", string(dump))
  34  		} else {
  35  			common.Debugln(e)
  36  		}
  37  	})
  38  
  39  	defer response.Body.Close()
  40  	if _, err = body.ReadFrom(response.Body); err != nil {
  41  		return
  42  	}
  43  
  44  	if statusCode != http.StatusOK {
  45  		err = fmt.Errorf("HTTP Get failed: URL: %s, Status: %s, Message: %s",
  46  			url, response.Status, body.String())
  47  		return
  48  	}
  49  
  50  	return
  51  }
  52  
  53  func extractTenancyIDFromCertificate(cert *x509.Certificate) string {
  54  	for _, nameAttr := range cert.Subject.Names {
  55  		value := nameAttr.Value.(string)
  56  		if strings.HasPrefix(value, "opc-tenant:") {
  57  			return value[len("opc-tenant:"):]
  58  		}
  59  	}
  60  	return ""
  61  }
  62  
  63  func fingerprint(certificate *x509.Certificate) string {
  64  	fingerprint := sha256.Sum256(certificate.Raw)
  65  	return colonSeparatedString(fingerprint)
  66  }
  67  
  68  func colonSeparatedString(fingerprint [sha256.Size]byte) string {
  69  	spaceSeparated := fmt.Sprintf("% x", fingerprint)
  70  	return strings.Replace(spaceSeparated, " ", ":", -1)
  71  }
  72  
  73  func sanitizeCertificateString(certString string) string {
  74  	certString = strings.Replace(certString, "-----BEGIN CERTIFICATE-----", "", -1)
  75  	certString = strings.Replace(certString, "-----END CERTIFICATE-----", "", -1)
  76  	certString = strings.Replace(certString, "-----BEGIN PUBLIC KEY-----", "", -1)
  77  	certString = strings.Replace(certString, "-----END PUBLIC KEY-----", "", -1)
  78  	certString = strings.Replace(certString, "\n", "", -1)
  79  	return certString
  80  }
  81  
  82  // GetGenericConfigurationProvider checks auth config paras in config file and return the final configuration provider
  83  func GetGenericConfigurationProvider(configProvider common.ConfigurationProvider) (common.ConfigurationProvider, error) {
  84  	if authConfig, err := configProvider.AuthType(); err == nil && authConfig.IsFromConfigFile {
  85  		switch authConfig.AuthType {
  86  		case common.InstancePrincipalDelegationToken:
  87  			if region, err := configProvider.Region(); err == nil {
  88  				return InstancePrincipalDelegationTokenConfigurationProviderForRegion(authConfig.OboToken, common.StringToRegion(region))
  89  			}
  90  			return InstancePrincipalDelegationTokenConfigurationProvider(authConfig.OboToken)
  91  		case common.InstancePrincipal:
  92  			return InstancePrincipalConfigurationProvider()
  93  		case common.UserPrincipal:
  94  			return configProvider, nil
  95  		}
  96  	}
  97  	return configProvider, nil
  98  }
  99