From 17f99c7d4b337c1e88d39af27ac9d6c13ff1d243 Mon Sep 17 00:00:00 2001 From: Karim Radhouani Date: Fri, 15 Nov 2024 21:34:53 -0800 Subject: [PATCH] do not return targets passwords in REST API requests --- pkg/api/types/target.go | 83 +++++++++++++++++++++++++++++++++++++++++ pkg/app/api.go | 38 +++++++++++++++++-- 2 files changed, 118 insertions(+), 3 deletions(-) diff --git a/pkg/api/types/target.go b/pkg/api/types/target.go index 042fab81..2130e66f 100644 --- a/pkg/api/types/target.go +++ b/pkg/api/types/target.go @@ -176,6 +176,89 @@ func (tc TargetConfig) String() string { return string(b) } +func (tc *TargetConfig) DeepCopy() *TargetConfig { + if tc == nil { + return nil + } + ntc := &TargetConfig{ + Name: tc.Name, + Address: tc.Address, + AuthScheme: tc.AuthScheme, + Timeout: tc.Timeout, + TLSServerName: tc.TLSServerName, + Subscriptions: make([]string, 0, len(tc.Subscriptions)), + Outputs: make([]string, 0, len(tc.Outputs)), + BufferSize: tc.BufferSize, + RetryTimer: tc.RetryTimer, + TLSMinVersion: tc.TLSMinVersion, + TLSMaxVersion: tc.TLSMaxVersion, + TLSVersion: tc.TLSVersion, + ProtoFiles: make([]string, 0, len(tc.ProtoFiles)), + ProtoDirs: make([]string, 0, len(tc.ProtoDirs)), + Tags: make([]string, 0, len(tc.Tags)), + EventTags: make(map[string]string, len(tc.EventTags)), + Proxy: tc.Proxy, + TunnelTargetType: tc.TunnelTargetType, + Metadata: make(map[string]string, len(tc.Metadata)), + CipherSuites: make([]string, 0, len(tc.CipherSuites)), + TCPKeepalive: tc.TCPKeepalive, + } + if tc.Username != nil { + ntc.Username = tc.Username + } + if tc.Password != nil { + ntc.Password = tc.Password + } + if tc.Insecure != nil { + ntc.Insecure = tc.Insecure + } + if tc.TLSCA != nil { + ntc.TLSCA = tc.TLSCA + } + if tc.TLSCert != nil { + ntc.TLSCert = tc.TLSCert + } + if tc.TLSKey != nil { + ntc.TLSKey = tc.TLSKey + } + if tc.SkipVerify != nil { + ntc.SkipVerify = tc.SkipVerify + } + if tc.LogTLSSecret != nil { + ntc.LogTLSSecret = tc.LogTLSSecret + } + if tc.Gzip != nil { + ntc.Gzip = tc.Gzip + } + if tc.Token != nil { + ntc.Token = tc.Token + } + if tc.Encoding != nil { + ntc.Encoding = tc.Encoding + } + ntc.Subscriptions = append(ntc.Subscriptions, tc.Subscriptions...) + ntc.Outputs = append(ntc.Outputs, tc.Outputs...) + ntc.ProtoFiles = append(ntc.ProtoFiles, tc.ProtoFiles...) + ntc.ProtoDirs = append(ntc.ProtoDirs, tc.ProtoDirs...) + ntc.Tags = append(ntc.Tags, tc.Tags...) + ntc.CipherSuites = append(ntc.CipherSuites, tc.CipherSuites...) + + for k, v := range tc.EventTags { + tc.EventTags[k] = v + } + for k, v := range tc.Metadata { + tc.Metadata[k] = v + } + if tc.GRPCKeepalive != nil { + ntc.GRPCKeepalive = &clientKeepalive{ + Time: tc.GRPCKeepalive.Time, + Timeout: tc.GRPCKeepalive.Timeout, + PermitWithoutStream: tc.GRPCKeepalive.PermitWithoutStream, + } + } + return ntc +} + func (tc *TargetConfig) SetTLSConfig(tlsConfig *tls.Config) { tc.tlsConfig = tlsConfig } diff --git a/pkg/app/api.go b/pkg/app/api.go index fbd9d0ff..3aaabf52 100644 --- a/pkg/app/api.go +++ b/pkg/app/api.go @@ -17,6 +17,7 @@ import ( "net/http" "strings" + "github.com/AlekSi/pointer" "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus/collectors" @@ -24,6 +25,7 @@ import ( "github.com/openconfig/gnmic/pkg/api/types" "github.com/openconfig/gnmic/pkg/api/utils" + "github.com/openconfig/gnmic/pkg/config" ) func (a *App) newAPIServer() (*http.Server, error) { @@ -78,7 +80,14 @@ func (a *App) handleConfigTargetsGet(w http.ResponseWriter, r *http.Request) { a.configLock.RLock() defer a.configLock.RUnlock() if id == "" { - err = json.NewEncoder(w).Encode(a.Config.Targets) + // copy targets map + targets := make(map[string]*types.TargetConfig, len(a.Config.Targets)) + for n, tc := range a.Config.Targets { + ntc := tc.DeepCopy() + ntc.Password = pointer.ToString("****") + targets[n] = ntc + } + err = json.NewEncoder(w).Encode(targets) if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(APIErrors{Errors: []string{err.Error()}}) @@ -86,7 +95,9 @@ func (a *App) handleConfigTargetsGet(w http.ResponseWriter, r *http.Request) { return } if t, ok := a.Config.Targets[id]; ok { - err = json.NewEncoder(w).Encode(t) + tc := t.DeepCopy() + tc.Password = pointer.ToString("****") + err = json.NewEncoder(w).Encode(tc) if err != nil { w.WriteHeader(http.StatusInternalServerError) json.NewEncoder(w).Encode(APIErrors{Errors: []string{err.Error()}}) @@ -192,7 +203,28 @@ func (a *App) handleConfigProcessors(w http.ResponseWriter, r *http.Request) { } func (a *App) handleConfig(w http.ResponseWriter, r *http.Request) { - a.handlerCommonGet(w, a.Config) + nc := &config.Config{ + GlobalFlags: a.Config.GlobalFlags, + LocalFlags: a.Config.LocalFlags, + FileConfig: a.Config.FileConfig, + Targets: make(map[string]*types.TargetConfig, len(a.Config.Targets)), + Subscriptions: a.Config.Subscriptions, + Outputs: a.Config.Outputs, + Inputs: a.Config.Inputs, + Processors: a.Config.Processors, + Clustering: a.Config.Clustering, + GnmiServer: a.Config.GnmiServer, + APIServer: a.Config.APIServer, + Loader: a.Config.Loader, + Actions: a.Config.Actions, + TunnelServer: a.Config.TunnelServer, + } + for n, t := range a.Config.Targets { + tc := t.DeepCopy() + tc.Password = pointer.ToString("****") + nc.Targets[n] = tc + } + a.handlerCommonGet(w, nc) } func (a *App) handleTargetsGet(w http.ResponseWriter, r *http.Request) {