@@ -3,35 +3,28 @@ package infa_auth
33import (
44 "context"
55 "crypto/tls"
6- "errors"
7- "io/ioutil"
8- "net/http"
9-
106 "crypto/x509"
7+ "errors"
118 "github.com/gofiber/fiber/v2/log"
9+ "github.com/lwithers/minijks/jks"
1210 "go.opentelemetry.io/collector/client"
1311 "go.opentelemetry.io/collector/component"
1412 "go.opentelemetry.io/collector/extension/auth"
1513 "go.uber.org/zap"
14+ "net/http"
1615 "os"
16+ "strings"
1717 "time"
1818)
1919
2020type infaAuthExtension struct {
21- cfg * Config
22- logger * zap.Logger
21+ cfg * Config
22+ logger * zap.Logger
23+ sessionServiceClient * http.Client
2324}
2425
2526func newExtension (ctx context.Context , cfg * Config , logger * zap.Logger ) (auth.Server , error ) {
26- /*
27- if cfg.ValidationURL == "" {
28- return nil, errors.New("validation url is empty")
29- }
3027
31- if cfg.Headerkey == "" {
32- return nil, errors.New("header key is empty")
33- }
34- */
3528 oe := & infaAuthExtension {
3629 cfg : cfg ,
3730 logger : logger ,
@@ -45,71 +38,76 @@ func (e *infaAuthExtension) start(context.Context, component.Host) error {
4538 log .Debug ("begin executing extension.start" )
4639
4740 //validation url and header key must NOT be empty
48- if e .cfg .ValidationURL == "" {
41+ if strings . TrimSpace ( e .cfg .ValidationURL ) == "" {
4942 return errors .New ("ValidationURL is empty" )
5043 }
5144
52- if e .cfg .Headerkey == "" {
45+ if strings . TrimSpace ( e .cfg .Headerkey ) == "" {
5346 return errors .New ("Headerkey is empty" )
5447 }
5548
56- /*
57- if e.cfg.CACertPath == "" {
58- log.Debug("CACertPath is empty")
59- return errors.New("CACertPath is empty")
60- }
49+ sessionServiceClient , err := getClient (e .cfg )
50+ e .sessionServiceClient = sessionServiceClient
51+ if err != nil {
52+ log .Debug ("error while creating client in extension.start" )
53+ return err
54+ }
6155
62- log.Debugf("CACertPath is : %s ", e.cfg.CACertPath)
63- _, error := os.Stat(e.cfg.CACertPath)
64- if error != nil {
65- log.Debugf("error reading CACertPath")
66- return errors.New("error reading CACertPath")
67- }
68- */
56+ log .Debugf ("finished executing extension.start , sessionServiceClient : %A" , sessionServiceClient )
57+ return nil
58+ }
6959
70- //validate client cert
71- log .Debugf ("ClientSideSsl is : %s " , e .cfg .ClientSideSsl )
72- if e .cfg .ClientSideSsl {
73- log .Debugf ("ClientCertPath is : %s " , e .cfg .ClientCertPath )
74- if e .cfg .ClientCertPath == "" {
75- log .Debug ("ClientCertPath is empty" )
76- return errors .New ("ClientCertPath is empty" )
77-
78- } else {
79- _ , error := os .Stat (e .cfg .ClientCertPath )
80- if error != nil {
81- log .Debugf ("error reading ClientCert" )
82- return errors .New ("error reading ClientCert" )
83- }
84- }
60+ func getJksKeystore (filename string , password string ) (* jks.Keystore , error ) {
8561
86- log .Debugf ("ClientKeyPath is : %s " , e .cfg .ClientKeyPath )
87- if e .cfg .ClientKeyPath == "" {
88- log .Debug ("ClientKeyPath is empty" )
89- return errors .New ("ClientKeyPath is empty" )
62+ jksContent , err := os .ReadFile (filename )
63+ if err != nil {
64+ return nil , err
65+ }
66+ log .Debug ("read keystorefile : " + filename )
9067
91- } else {
92- _ , error := os . Stat ( e . cfg . ClientKeyPath )
93- if error != nil {
94- log . Debugf ( "error reading ClientKeyPath" )
95- return errors . New ( "error reading ClientKeyPath" )
96- }
68+ var opts * jks. Options
69+ if strings . TrimSpace ( password ) == "" {
70+ log . Debug ( "password is empty , will use nil options" )
71+ } else {
72+ opts = & jks. Options {
73+ Password : password ,
9774 }
75+ }
9876
77+ keyStore , err := jks .Parse (jksContent , opts )
78+ if err != nil {
79+ return nil , err
9980 }
81+ log .Debug ("success read keystorefile : " + filename )
82+ return keyStore , nil
83+ }
10084
101- log .Debug ("finished executing extension.start" )
102- return nil
85+ func getClientCert (ks jks.Keystore ) (* tls.Certificate , error ) {
86+ cert , err := tls .X509KeyPair (ks .Keypairs [0 ].CertChain [0 ].Cert .Raw , ks .Keypairs [0 ].RawKey )
87+ if err != nil {
88+ log .Debugf ("getClientCert ERR %A" , err )
89+ }
90+ return & cert , nil
91+ }
92+
93+ func getCACertPool (ks jks.Keystore ) (* x509.CertPool , error ) {
94+ pool := x509 .NewCertPool ()
95+ for i := 0 ; i < len (ks .Certs ); i ++ {
96+ log .Debugf ("adding CA cert to pool : " + string (ks .Certs [i ].Alias ))
97+ pool .AddCert (ks .Certs [i ].Cert )
98+ }
99+ return pool , nil
103100}
104101
105102// authenticate checks whether the given context contains valid auth data. Successfully authenticated calls will always return a nil error and a context with the auth data.
106103// this associated to the Authenticate() method
107104func (e * infaAuthExtension ) authenticate (ctx context.Context , headers map [string ][]string ) (context.Context , error ) {
108105 log .Debug ("executing extensions.authenticate() " )
109- log .Debugf ("headers :: %A" , headers )
110- log .Debugf ("ctx :: %A" , ctx )
111- log .Debugf ("e.cfg :: %A" , * e .cfg )
112-
106+ /*
107+ log.Debugf("headers :: %A", headers)
108+ log.Debugf("ctx :: %A", ctx)
109+ log.Debugf("e.cfg :: %A", *e.cfg)
110+ */
113111 var h []string
114112
115113 h = headers ["Ids-Agent-Session-Id" ]
@@ -134,81 +132,89 @@ func (e *infaAuthExtension) authenticate(ctx context.Context, headers map[string
134132 }
135133
136134 cl := client .FromContext (ctx )
137- status , err := validateToken (e . cfg , token )
138- if err != nil || status == false {
135+ status , err := validateToken (e , token )
136+ if err != nil || ! status {
139137 return ctx , err
140138 }
141139
142140 //success
143141 return client .NewContext (ctx , cl ), nil
144142}
145143
146- // this method creates a HTTP client and makes HTTP/S request to session service, if http status is 200 , it returns
147- // true with nil error , otherwise non-nil error is returned
148- func validateToken (cfg * Config , sessionToken string ) (bool , error ) {
149- // Create an HTTP client
150- log .Debug ("calling extension.validateToken() " )
151-
144+ func getClient (cfg * Config ) (* http.Client , error ) {
145+ var pool * x509.CertPool
146+ var clientCert * tls.Certificate
147+ client := & http.Client {
148+ Timeout : func () time.Duration {
149+ if cfg .TimeOut > 0 {
150+ return time .Duration (cfg .TimeOut ) * time .Second
151+ }
152+ return 2 * time .Second
153+ }(),
154+ }
152155 tr := & http.Transport {}
156+ client .Transport = tr
153157
154- //read ca-cert file
155- pool := x509 .NewCertPool ()
156- if cfg .CACertPath != "" {
157- cert , err := ioutil .ReadFile (cfg .CACertPath )
158- if err != nil {
159- log .Debugf ("Error reading CA certificate: %A" , err )
160- return false , err
161- } else {
162- pool .AppendCertsFromPEM (cert )
163- tr = & http.Transport {
164- TLSClientConfig : & tls.Config {InsecureSkipVerify : cfg .InsecureSkipVerify , RootCAs : pool },
165- }
166- }
158+ //create client with no TLS
159+ if cfg .InsecureSkipVerify {
160+ tr .TLSClientConfig = & tls.Config {InsecureSkipVerify : true }
161+ log .Info ("returning client block1 " )
162+ return client , nil
167163 } else {
168- tr = & http.Transport {
169- TLSClientConfig : & tls.Config {InsecureSkipVerify : cfg .InsecureSkipVerify },
170- }
171- }
164+ //create client with TLS , CACert is mandatory clientCert is optional
165+ caKs , err := getJksKeystore (cfg .CAJksPath , cfg .CAJksPassword )
172166
173- // Load client certificate and private key
174- if cfg .ClientSideSsl {
175- cert , err := tls .LoadX509KeyPair (cfg .ClientCertPath , cfg .ClientKeyPath )
176167 if err != nil {
177- log .Debugf ( "Error loading client certificate:" , err )
178- return false , err
168+ log .Info ( "error while reading CA jksKeystore : " + cfg . CAJksPath )
169+ return nil , err
179170 }
180- config := & tls.Config {
181- Certificates : []tls.Certificate {cert },
182- RootCAs : pool ,
183- InsecureSkipVerify : cfg .InsecureSkipVerify ,
171+
172+ pool , err = getCACertPool (* caKs )
173+ if err != nil {
174+ log .Info ("error while generating CACertPool : " + cfg .CAJksPath )
175+ return nil , err
184176 }
185- tr = & http.Transport {
186- TLSClientConfig : config ,
177+
178+ tr .TLSClientConfig = & tls.Config {InsecureSkipVerify : false , RootCAs : pool }
179+
180+ if cfg .ClientSideSsl {
181+ clientKs , err := getJksKeystore (cfg .ClientJksPath , cfg .ClientJksPassword )
182+ if err != nil {
183+ log .Info ("error while reading Client jksKeystore : " + cfg .ClientJksPath )
184+ return nil , err
185+ }
186+
187+ clientCert , err = getClientCert (* clientKs )
188+ if err != nil {
189+ log .Info ("error while creating Client cert : " + cfg .ClientJksPath )
190+ return nil , err
191+ }
192+
193+ tr .TLSClientConfig .Certificates = []tls.Certificate {* clientCert }
187194 }
188- }
189195
190- client := & http.Client {}
191- if cfg .TimeOut > 0 {
192- client = & http.Client {
193- Timeout : time .Duration (cfg .TimeOut ) * time .Second ,
194- Transport : tr }
195- } else {
196- client = & http.Client {
197- Timeout : 2 * time .Second ,
198- Transport : tr }
196+ log .Info ("returning client block2 " )
197+ client .Transport = tr
198+ return client , nil
199199 }
200+ }
200201
201- req , err := http .NewRequest ("GET" , cfg .ValidationURL , nil )
202+ // this method creates a HTTP client and makes HTTP/S request to session service, if http status is 200 , it returns
203+ // true with nil error , otherwise non-nil error is returned
204+ func validateToken (e * infaAuthExtension , sessionToken string ) (bool , error ) {
205+ // Create an HTTP client
206+ log .Debug ("calling extension.validateToken() " )
207+ req , err := http .NewRequest ("GET" , e .cfg .ValidationURL , nil )
202208 if err != nil {
203209 log .Debugf ("Error creating request:" , err )
204210 return false , err
205211 }
206212
207- req .Header .Add (cfg .Headerkey , sessionToken )
213+ req .Header .Add (e . cfg .Headerkey , sessionToken )
208214
209215 // Make the request
210216 log .Debugf ("invoking http request : %A" , req )
211- resp , err := client .Do (req )
217+ resp , err := e . sessionServiceClient .Do (req )
212218 log .Debugf ("got response %A" , resp )
213219
214220 if err != nil {
@@ -218,20 +224,15 @@ func validateToken(cfg *Config, sessionToken string) (bool, error) {
218224
219225 if resp .StatusCode != 200 {
220226 log .Debug ("http status is not 200 in response" )
221- return false , errors .New ("http status is not 200 in response" )
227+ body := make ([]byte , 1024 )
228+ _ , err := resp .Body .Read (body )
229+ if err != nil {
230+ log .Debugf ("Error reading response body:" , err )
231+ return false , err
232+ }
233+ return false , errors .New ("http status is not 200 in response response body is " + string (body ))
222234 }
223235
224236 defer resp .Body .Close ()
225-
226- // Read the response body
227- body , err := ioutil .ReadAll (resp .Body )
228- if err != nil {
229- log .Debugf ("Error reading response body:" , err )
230- return false , err
231- }
232-
233- // Print the response
234- log .Debugf ("response body is %A" , string (body ))
235237 return true , nil
236-
237238}
0 commit comments