| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- package service
- import (
- "log"
- "net/http"
- "time"
- "github.com/jcmturner/gokrb5/v8/keytab"
- "github.com/jcmturner/gokrb5/v8/types"
- )
- // Settings defines service side configuration settings.
- type Settings struct {
- Keytab *keytab.Keytab
- ktprinc *types.PrincipalName
- sname string
- requireHostAddr bool
- disablePACDecoding bool
- cAddr types.HostAddress
- maxClockSkew time.Duration
- logger *log.Logger
- sessionMgr SessionMgr
- }
- // NewSettings creates a new service Settings.
- func NewSettings(kt *keytab.Keytab, settings ...func(*Settings)) *Settings {
- s := new(Settings)
- s.Keytab = kt
- for _, set := range settings {
- set(s)
- }
- return s
- }
- // RequireHostAddr used to configure service side to required host addresses to be specified in Kerberos tickets.
- //
- // s := NewSettings(kt, RequireHostAddr(true))
- func RequireHostAddr(b bool) func(*Settings) {
- return func(s *Settings) {
- s.requireHostAddr = b
- }
- }
- // RequireHostAddr indicates if the service should require the host address to be included in the ticket.
- func (s *Settings) RequireHostAddr() bool {
- return s.requireHostAddr
- }
- // DecodePAC used to configure service side to enable/disable PAC decoding if the PAC is present.
- // Defaults to enabled if not specified.
- //
- // s := NewSettings(kt, DecodePAC(false))
- func DecodePAC(b bool) func(*Settings) {
- return func(s *Settings) {
- s.disablePACDecoding = !b
- }
- }
- // DecodePAC indicates whether the service should decode any PAC information present in the ticket.
- func (s *Settings) DecodePAC() bool {
- return !s.disablePACDecoding
- }
- // ClientAddress used to configure service side with the clients host address to be used during validation.
- //
- // s := NewSettings(kt, ClientAddress(h))
- func ClientAddress(h types.HostAddress) func(*Settings) {
- return func(s *Settings) {
- s.cAddr = h
- }
- }
- // ClientAddress returns the client host address which has been provided to the service.
- func (s *Settings) ClientAddress() types.HostAddress {
- return s.cAddr
- }
- // Logger used to configure service side with a logger.
- //
- // s := NewSettings(kt, Logger(l))
- func Logger(l *log.Logger) func(*Settings) {
- return func(s *Settings) {
- s.logger = l
- }
- }
- // Logger returns the logger instances configured for the service. If none is configured nill will be returned.
- func (s *Settings) Logger() *log.Logger {
- return s.logger
- }
- // KeytabPrincipal used to override the principal name used to find the key in the keytab.
- //
- // s := NewSettings(kt, KeytabPrincipal("someaccount"))
- func KeytabPrincipal(p string) func(*Settings) {
- return func(s *Settings) {
- pn, _ := types.ParseSPNString(p)
- s.ktprinc = &pn
- }
- }
- // KeytabPrincipal returns the principal name used to find the key in the keytab if it has been overridden.
- func (s *Settings) KeytabPrincipal() *types.PrincipalName {
- return s.ktprinc
- }
- // MaxClockSkew used to configure service side with the maximum acceptable clock skew
- // between the service and the issue time of kerberos tickets
- //
- // s := NewSettings(kt, MaxClockSkew(d))
- func MaxClockSkew(d time.Duration) func(*Settings) {
- return func(s *Settings) {
- s.maxClockSkew = d
- }
- }
- // MaxClockSkew returns the maximum acceptable clock skew between the service and the issue time of kerberos tickets.
- // If none is defined a duration of 5 minutes is returned.
- func (s *Settings) MaxClockSkew() time.Duration {
- if s.maxClockSkew.Nanoseconds() == 0 {
- return time.Duration(5) * time.Minute
- }
- return s.maxClockSkew
- }
- // SName used provide a specific service name to the service settings.
- //
- // s := NewSettings(kt, SName("HTTP/some.service.com"))
- func SName(sname string) func(*Settings) {
- return func(s *Settings) {
- s.sname = sname
- }
- }
- // SName returns the specific service name to the service.
- func (s *Settings) SName() string {
- return s.sname
- }
- // SessionManager configures a session manager to establish sessions with clients to avoid excessive authentication challenges.
- //
- // s := NewSettings(kt, SessionManager(sm))
- func SessionManager(sm SessionMgr) func(*Settings) {
- return func(s *Settings) {
- s.sessionMgr = sm
- }
- }
- // SessionManager returns any configured session manager.
- func (s *Settings) SessionManager() SessionMgr {
- return s.sessionMgr
- }
- // SessionMgr must provide a ways to:
- //
- // - Create new sessions and in the process add a value to the session under the key provided.
- //
- // - Get an existing session returning the value in the session under the key provided.
- // Return nil bytes and/or error if there is no session.
- type SessionMgr interface {
- New(w http.ResponseWriter, r *http.Request, k string, v []byte) error
- Get(r *http.Request, k string) ([]byte, error)
- }
|