settings.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package service
  2. import (
  3. "log"
  4. "net/http"
  5. "time"
  6. "github.com/jcmturner/gokrb5/v8/keytab"
  7. "github.com/jcmturner/gokrb5/v8/types"
  8. )
  9. // Settings defines service side configuration settings.
  10. type Settings struct {
  11. Keytab *keytab.Keytab
  12. ktprinc *types.PrincipalName
  13. sname string
  14. requireHostAddr bool
  15. disablePACDecoding bool
  16. cAddr types.HostAddress
  17. maxClockSkew time.Duration
  18. logger *log.Logger
  19. sessionMgr SessionMgr
  20. }
  21. // NewSettings creates a new service Settings.
  22. func NewSettings(kt *keytab.Keytab, settings ...func(*Settings)) *Settings {
  23. s := new(Settings)
  24. s.Keytab = kt
  25. for _, set := range settings {
  26. set(s)
  27. }
  28. return s
  29. }
  30. // RequireHostAddr used to configure service side to required host addresses to be specified in Kerberos tickets.
  31. //
  32. // s := NewSettings(kt, RequireHostAddr(true))
  33. func RequireHostAddr(b bool) func(*Settings) {
  34. return func(s *Settings) {
  35. s.requireHostAddr = b
  36. }
  37. }
  38. // RequireHostAddr indicates if the service should require the host address to be included in the ticket.
  39. func (s *Settings) RequireHostAddr() bool {
  40. return s.requireHostAddr
  41. }
  42. // DecodePAC used to configure service side to enable/disable PAC decoding if the PAC is present.
  43. // Defaults to enabled if not specified.
  44. //
  45. // s := NewSettings(kt, DecodePAC(false))
  46. func DecodePAC(b bool) func(*Settings) {
  47. return func(s *Settings) {
  48. s.disablePACDecoding = !b
  49. }
  50. }
  51. // DecodePAC indicates whether the service should decode any PAC information present in the ticket.
  52. func (s *Settings) DecodePAC() bool {
  53. return !s.disablePACDecoding
  54. }
  55. // ClientAddress used to configure service side with the clients host address to be used during validation.
  56. //
  57. // s := NewSettings(kt, ClientAddress(h))
  58. func ClientAddress(h types.HostAddress) func(*Settings) {
  59. return func(s *Settings) {
  60. s.cAddr = h
  61. }
  62. }
  63. // ClientAddress returns the client host address which has been provided to the service.
  64. func (s *Settings) ClientAddress() types.HostAddress {
  65. return s.cAddr
  66. }
  67. // Logger used to configure service side with a logger.
  68. //
  69. // s := NewSettings(kt, Logger(l))
  70. func Logger(l *log.Logger) func(*Settings) {
  71. return func(s *Settings) {
  72. s.logger = l
  73. }
  74. }
  75. // Logger returns the logger instances configured for the service. If none is configured nill will be returned.
  76. func (s *Settings) Logger() *log.Logger {
  77. return s.logger
  78. }
  79. // KeytabPrincipal used to override the principal name used to find the key in the keytab.
  80. //
  81. // s := NewSettings(kt, KeytabPrincipal("someaccount"))
  82. func KeytabPrincipal(p string) func(*Settings) {
  83. return func(s *Settings) {
  84. pn, _ := types.ParseSPNString(p)
  85. s.ktprinc = &pn
  86. }
  87. }
  88. // KeytabPrincipal returns the principal name used to find the key in the keytab if it has been overridden.
  89. func (s *Settings) KeytabPrincipal() *types.PrincipalName {
  90. return s.ktprinc
  91. }
  92. // MaxClockSkew used to configure service side with the maximum acceptable clock skew
  93. // between the service and the issue time of kerberos tickets
  94. //
  95. // s := NewSettings(kt, MaxClockSkew(d))
  96. func MaxClockSkew(d time.Duration) func(*Settings) {
  97. return func(s *Settings) {
  98. s.maxClockSkew = d
  99. }
  100. }
  101. // MaxClockSkew returns the maximum acceptable clock skew between the service and the issue time of kerberos tickets.
  102. // If none is defined a duration of 5 minutes is returned.
  103. func (s *Settings) MaxClockSkew() time.Duration {
  104. if s.maxClockSkew.Nanoseconds() == 0 {
  105. return time.Duration(5) * time.Minute
  106. }
  107. return s.maxClockSkew
  108. }
  109. // SName used provide a specific service name to the service settings.
  110. //
  111. // s := NewSettings(kt, SName("HTTP/some.service.com"))
  112. func SName(sname string) func(*Settings) {
  113. return func(s *Settings) {
  114. s.sname = sname
  115. }
  116. }
  117. // SName returns the specific service name to the service.
  118. func (s *Settings) SName() string {
  119. return s.sname
  120. }
  121. // SessionManager configures a session manager to establish sessions with clients to avoid excessive authentication challenges.
  122. //
  123. // s := NewSettings(kt, SessionManager(sm))
  124. func SessionManager(sm SessionMgr) func(*Settings) {
  125. return func(s *Settings) {
  126. s.sessionMgr = sm
  127. }
  128. }
  129. // SessionManager returns any configured session manager.
  130. func (s *Settings) SessionManager() SessionMgr {
  131. return s.sessionMgr
  132. }
  133. // SessionMgr must provide a ways to:
  134. //
  135. // - Create new sessions and in the process add a value to the session under the key provided.
  136. //
  137. // - Get an existing session returning the value in the session under the key provided.
  138. // Return nil bytes and/or error if there is no session.
  139. type SessionMgr interface {
  140. New(w http.ResponseWriter, r *http.Request, k string, v []byte) error
  141. Get(r *http.Request, k string) ([]byte, error)
  142. }