Skip to content

Commit

Permalink
feat(fips): return an error when creating a kerberos client (#42597) (#…
Browse files Browse the repository at this point in the history
…42881)

* feat(fips): return an error when creating a kerberos client

kerberos lib is implementing a lot of crypto :(

* test: add kerberos client tests

---------

Co-authored-by: Pierre HILBERT <[email protected]>
(cherry picked from commit bbfa290)

Co-authored-by: kruskall <[email protected]>
  • Loading branch information
mergify[bot] and kruskall authored Feb 27, 2025
1 parent 89ae1e0 commit 30ac154
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 40 deletions.
43 changes: 3 additions & 40 deletions libbeat/common/transport/kerberos/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,11 @@
package kerberos

import (
"fmt"
"net/http"

krbclient "github.com/jcmturner/gokrb5/v8/client"
krbconfig "github.com/jcmturner/gokrb5/v8/config"
"github.com/jcmturner/gokrb5/v8/keytab"
"github.com/jcmturner/gokrb5/v8/spnego"
)

type Client struct {
spClient *spnego.Client
}

func NewClient(config *Config, httpClient *http.Client, esurl string) (*Client, error) {
var krbClient *krbclient.Client
krbConf, err := krbconfig.Load(config.ConfigPath)
if err != nil {
return nil, fmt.Errorf("error creating Kerberos client: %w", err)
}

switch config.AuthType {
case authKeytab:
kTab, err := keytab.Load(config.KeyTabPath)
if err != nil {
return nil, fmt.Errorf("cannot load keytab file %s: %w", config.KeyTabPath, err)
}
krbClient = krbclient.NewWithKeytab(config.Username, config.Realm, kTab, krbConf)
case authPassword:
krbClient = krbclient.NewWithPassword(config.Username, config.Realm, config.Password, krbConf)
default:
return nil, InvalidAuthType
}

return &Client{
spClient: spnego.NewClient(krbClient, httpClient, ""),
}, nil
}

func (c *Client) Do(req *http.Request) (*http.Response, error) {
return c.spClient.Do(req)
}
type Client interface {
Do(req *http.Request) (*http.Response, error)

func (c *Client) CloseIdleConnections() {
c.spClient.CloseIdleConnections()
CloseIdleConnections()
}
29 changes: 29 additions & 0 deletions libbeat/common/transport/kerberos/client_fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build requirefips

package kerberos

import (
"errors"
"net/http"
)

func NewClient(config *Config, httpClient *http.Client, esurl string) (Client, error) {
return nil, errors.New("kerberos is not supported in fips mode")
}
39 changes: 39 additions & 0 deletions libbeat/common/transport/kerberos/client_fips_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build requirefips

package kerberos

import (
"net/http"
"os"
"testing"

"github.com/stretchr/testify/require"
)

func TestNewClient(t *testing.T) {
cfg, err := os.CreateTemp(t.TempDir(), "config")
require.NoError(t, err)
c, err := NewClient(&Config{
AuthType: authPassword,
ConfigPath: cfg.Name(),
}, http.DefaultClient, "")
require.Nil(t, c)
require.EqualError(t, err, "kerberos is not supported in fips mode")
}
53 changes: 53 additions & 0 deletions libbeat/common/transport/kerberos/client_nofips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build !requirefips

package kerberos

import (
"fmt"
"net/http"

krbclient "github.com/jcmturner/gokrb5/v8/client"
krbconfig "github.com/jcmturner/gokrb5/v8/config"
"github.com/jcmturner/gokrb5/v8/keytab"
"github.com/jcmturner/gokrb5/v8/spnego"
)

func NewClient(config *Config, httpClient *http.Client, esurl string) (Client, error) {
var krbClient *krbclient.Client
krbConf, err := krbconfig.Load(config.ConfigPath)
if err != nil {
return nil, fmt.Errorf("error creating Kerberos client: %w", err)
}

switch config.AuthType {
case authKeytab:
kTab, err := keytab.Load(config.KeyTabPath)
if err != nil {
return nil, fmt.Errorf("cannot load keytab file %s: %w", config.KeyTabPath, err)
}
krbClient = krbclient.NewWithKeytab(config.Username, config.Realm, kTab, krbConf)
case authPassword:
krbClient = krbclient.NewWithPassword(config.Username, config.Realm, config.Password, krbConf)
default:
return nil, InvalidAuthType
}

return spnego.NewClient(krbClient, httpClient, ""), nil
}
39 changes: 39 additions & 0 deletions libbeat/common/transport/kerberos/client_nofips_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//go:build !requirefips

package kerberos

import (
"net/http"
"os"
"testing"

"github.com/stretchr/testify/require"
)

func TestNewClient(t *testing.T) {
cfg, err := os.CreateTemp(t.TempDir(), "config")
require.NoError(t, err)
c, err := NewClient(&Config{
AuthType: authPassword,
ConfigPath: cfg.Name(),
}, http.DefaultClient, "")
require.Nil(t, err)
require.NotNil(t, c)
}

0 comments on commit 30ac154

Please sign in to comment.