diff --git a/go.mod b/go.mod index fe3f97fd..4190a571 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/free5gc/aper v1.0.5-0.20230614030933-c73735898582 github.com/free5gc/nas v1.1.2-0.20230828074825-175b09665828 github.com/free5gc/ngap v1.0.7-0.20230614061954-9c128114ab1f - github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 + github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6 github.com/free5gc/sctp v0.0.0-20231121085449-400a702ea7f9 github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94 github.com/gin-contrib/cors v1.3.1 diff --git a/go.sum b/go.sum index 7250855e..ff48dde4 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/free5gc/nas v1.1.2-0.20230828074825-175b09665828/go.mod h1:fjWwpyp7/w github.com/free5gc/ngap v1.0.7-0.20230614061954-9c128114ab1f h1:wgXjoknZ7JJoZ72J15g/f2/0DgdCpfcTg189lnhUPuY= github.com/free5gc/ngap v1.0.7-0.20230614061954-9c128114ab1f/go.mod h1:lKA1sLTYM3CGEBhZVxkGGJIkai5+Bvy2yHIMhb7Vx/k= github.com/free5gc/openapi v1.0.6/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= -github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 h1:BSIvKCYu7646sE8J9R1L8v2R435otUik3wOFN33csfs= -github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= +github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6 h1:8P/wOkTAQMgZJe9pUUNSTE5PWeAdlMrsU9kLsI+VAVE= +github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6/go.mod h1:qv9KqEucoZSeENPRFGxfTe+33ZWYyiYFx1Rj+H0DoWA= github.com/free5gc/sctp v0.0.0-20231121085449-400a702ea7f9 h1:L02UI8oODfXgH1fGzWWuWF4zyze4IScEFm20q3PKZdE= github.com/free5gc/sctp v0.0.0-20231121085449-400a702ea7f9/go.mod h1:Nr81VlvMkBHZsCbWPXjosBh+SWLdeEyz8o0OrS110Ic= github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94 h1:tNylIqH/m5Kq+3KuC+jjXGl06Y6EmM8yq61ZUgNrPBY= @@ -556,6 +556,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/context/context.go b/internal/context/context.go index 31906f90..afc9391a 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -1,6 +1,7 @@ package context import ( + "context" "fmt" "math" "net" @@ -18,6 +19,7 @@ import ( "github.com/free5gc/nas/security" "github.com/free5gc/openapi" "github.com/free5gc/openapi/models" + "github.com/free5gc/openapi/oauth" "github.com/free5gc/util/idgenerator" ) @@ -66,6 +68,7 @@ type AMFContext struct { SupportDnnLists []string AMFStatusSubscriptions sync.Map // map[subscriptionID]models.SubscriptionData NrfUri string + NrfCertPem string SecurityAlgorithm SecurityAlgorithm NetworkName factory.NetworkName NgapIpList []string // NGAP Server IP @@ -83,6 +86,8 @@ type AMFContext struct { T3570Cfg factory.TimerValue T3555Cfg factory.TimerValue Locality string + + OAuth2Required bool } type AMFContextEventSubscription struct { @@ -126,6 +131,7 @@ func InitAmfContext(context *AMFContext) { context.LadnPool[ladn.Dnn] = ladn } context.NrfUri = config.GetNrfUri() + context.NrfCertPem = configuration.NrfCertPem security := configuration.Security if security != nil { context.SecurityAlgorithm.IntegrityOrder = getIntAlgOrder(security.IntegrityOrder) @@ -536,9 +542,21 @@ func (context *AMFContext) Reset() { context.HttpIPv6Address = "" context.Name = "amf" context.NrfUri = "" + context.NrfCertPem = "" + context.OAuth2Required = false } // Create new AMF context func GetSelf() *AMFContext { return &amfContext } + +func (c *AMFContext) GetTokenCtx(scope, targetNF string) ( + context.Context, *models.ProblemDetails, error, +) { + if !c.OAuth2Required { + return context.TODO(), nil, nil + } + return oauth.GetTokenCtx(models.NfType_AMF, + c.NfId, c.NrfUri, scope, targetNF) +} diff --git a/internal/sbi/consumer/nf_discovery.go b/internal/sbi/consumer/nf_discovery.go index 421d4a0c..ada46d33 100644 --- a/internal/sbi/consumer/nf_discovery.go +++ b/internal/sbi/consumer/nf_discovery.go @@ -1,7 +1,6 @@ package consumer import ( - "context" "fmt" "net/http" @@ -14,18 +13,23 @@ import ( func SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfType, param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts, -) (models.SearchResult, error) { +) (*models.SearchResult, error) { // Set client and set url configuration := Nnrf_NFDiscovery.NewConfiguration() configuration.SetBasePath(nrfUri) client := Nnrf_NFDiscovery.NewAPIClient(configuration) - result, res, err := client.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType, requestNfType, param) + ctx, _, err := amf_context.GetSelf().GetTokenCtx("nnrf-nfm", "NRF") + if err != nil { + return nil, err + } + + result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, param) if res != nil && res.StatusCode == http.StatusTemporaryRedirect { err = fmt.Errorf("Temporary Redirect For Non NRF Consumer") } if res == nil || res.Body == nil { - return result, err + return &result, err } defer func() { if res != nil { @@ -34,7 +38,7 @@ func SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfT } } }() - return result, err + return &result, err } func SearchUdmSdmInstance(ue *amf_context.AmfUe, nrfUri string, targetNfType, requestNfType models.NfType, diff --git a/internal/sbi/consumer/nf_mangement.go b/internal/sbi/consumer/nf_mangement.go index f99c31a8..d5b8cc3d 100644 --- a/internal/sbi/consumer/nf_mangement.go +++ b/internal/sbi/consumer/nf_mangement.go @@ -80,8 +80,9 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil client := Nnrf_NFManagement.NewAPIClient(configuration) var res *http.Response + var nf models.NfProfile for { - _, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile) + nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile) if err != nil || res == nil { // TODO : add log fmt.Println(fmt.Errorf("AMF register to NRF Error[%s]", err.Error())) @@ -104,6 +105,20 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil resourceUri := res.Header.Get("Location") resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")] retrieveNfInstanceId = resourceUri[strings.LastIndex(resourceUri, "/")+1:] + + oauth2 := false + if nf.CustomInfo != nil { + v, ok := nf.CustomInfo["oauth2"].(bool) + if ok { + oauth2 = v + logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2) + } + } + amf_context.GetSelf().OAuth2Required = oauth2 + if oauth2 && amf_context.GetSelf().NrfCertPem == "" { + logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.") + } + break } else { fmt.Println(fmt.Errorf("handler returned wrong status code %d", status)) @@ -116,6 +131,11 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) { logger.ConsumerLog.Infof("[AMF] Send Deregister NFInstance") + ctx, pd, err := amf_context.GetSelf().GetTokenCtx("nnrf-nfm", "NRF") + if err != nil { + return pd, err + } + amfSelf := amf_context.GetSelf() // Set client and set url configuration := Nnrf_NFManagement.NewConfiguration() @@ -124,9 +144,9 @@ func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err erro var res *http.Response - res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(context.Background(), amfSelf.NfId) + res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, amfSelf.NfId) if err == nil { - return + return problemDetails, err } else if res != nil { defer func() { if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil { @@ -134,12 +154,12 @@ func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err erro } }() if res.Status != err.Error() { - return + return problemDetails, err } problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) problemDetails = &problem } else { err = openapi.ReportError("server no response") } - return + return problemDetails, err } diff --git a/internal/sbi/consumer/subscriber_data_management.go b/internal/sbi/consumer/subscriber_data_management.go index cf1a64e8..95a8e809 100644 --- a/internal/sbi/consumer/subscriber_data_management.go +++ b/internal/sbi/consumer/subscriber_data_management.go @@ -240,11 +240,11 @@ func SDMUnsubscribe(ue *amf_context.AmfUe) (problemDetails *models.ProblemDetail } }() if localErr == nil { - return + return problemDetails, err } else if httpResp != nil { if httpResp.Status != localErr.Error() { err = localErr - return + return problemDetails, err } problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) problemDetails = &problem diff --git a/pkg/factory/config.go b/pkg/factory/config.go index 51239e10..252a94bc 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -75,6 +75,7 @@ type Configuration struct { SupportDnnList []string `yaml:"supportDnnList,omitempty" valid:"required"` SupportLadnList []Ladn `yaml:"supportLadnList,omitempty" valid:"optional"` NrfUri string `yaml:"nrfUri,omitempty" valid:"required, url"` + NrfCertPem string `yaml:"nrfCertPem,omitempty" valid:"optional"` Security *Security `yaml:"security,omitempty" valid:"required"` NetworkName NetworkName `yaml:"networkName,omitempty" valid:"required"` NgapIE *NgapIE `yaml:"ngapIE,omitempty" valid:"optional"`