credentials.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // Package credentials provides credentials management for Kerberos 5 authentication.
  2. package credentials
  3. import (
  4. "time"
  5. "github.com/hashicorp/go-uuid"
  6. "gopkg.in/jcmturner/gokrb5.v6/iana/nametype"
  7. "gopkg.in/jcmturner/gokrb5.v6/keytab"
  8. "gopkg.in/jcmturner/gokrb5.v6/types"
  9. )
  10. const (
  11. // AttributeKeyADCredentials assigned number for AD credentials.
  12. AttributeKeyADCredentials = "gokrb5AttributeKeyADCredentials"
  13. )
  14. // Credentials struct for a user.
  15. // Contains either a keytab, password or both.
  16. // Keytabs are used over passwords if both are defined.
  17. type Credentials struct {
  18. Username string
  19. displayName string
  20. Realm string
  21. CName types.PrincipalName
  22. Keytab keytab.Keytab
  23. Password string
  24. attributes map[string]interface{}
  25. ValidUntil time.Time
  26. authenticated bool
  27. human bool
  28. authTime time.Time
  29. groupMembership map[string]bool
  30. sessionID string
  31. }
  32. // ADCredentials contains information obtained from the PAC.
  33. type ADCredentials struct {
  34. EffectiveName string
  35. FullName string
  36. UserID int
  37. PrimaryGroupID int
  38. LogOnTime time.Time
  39. LogOffTime time.Time
  40. PasswordLastSet time.Time
  41. GroupMembershipSIDs []string
  42. LogonDomainName string
  43. LogonDomainID string
  44. LogonServer string
  45. }
  46. // NewCredentials creates a new Credentials instance.
  47. func NewCredentials(username string, realm string) Credentials {
  48. uid, err := uuid.GenerateUUID()
  49. if err != nil {
  50. uid = "00unique-sess-ions-uuid-unavailable0"
  51. }
  52. return Credentials{
  53. Username: username,
  54. displayName: username,
  55. Realm: realm,
  56. CName: types.NewPrincipalName(nametype.KRB_NT_PRINCIPAL, username),
  57. Keytab: keytab.NewKeytab(),
  58. attributes: make(map[string]interface{}),
  59. sessionID: uid,
  60. }
  61. }
  62. // NewCredentialsFromPrincipal creates a new Credentials instance with the user details provides as a PrincipalName type.
  63. func NewCredentialsFromPrincipal(cname types.PrincipalName, realm string) Credentials {
  64. uid, err := uuid.GenerateUUID()
  65. if err != nil {
  66. uid = "00unique-sess-ions-uuid-unavailable0"
  67. }
  68. return Credentials{
  69. Username: cname.GetPrincipalNameString(),
  70. displayName: cname.GetPrincipalNameString(),
  71. Realm: realm,
  72. CName: cname,
  73. Keytab: keytab.NewKeytab(),
  74. attributes: make(map[string]interface{}),
  75. groupMembership: make(map[string]bool),
  76. sessionID: uid,
  77. }
  78. }
  79. // WithKeytab sets the Keytab in the Credentials struct.
  80. func (c *Credentials) WithKeytab(kt keytab.Keytab) *Credentials {
  81. c.Keytab = kt
  82. return c
  83. }
  84. // WithPassword sets the password in the Credentials struct.
  85. func (c *Credentials) WithPassword(password string) *Credentials {
  86. c.Password = password
  87. return c
  88. }
  89. // HasKeytab queries if the Credentials has a keytab defined.
  90. func (c *Credentials) HasKeytab() bool {
  91. if len(c.Keytab.Entries) > 0 {
  92. return true
  93. }
  94. return false
  95. }
  96. // SetValidUntil sets the expiry time of the credentials
  97. func (c *Credentials) SetValidUntil(t time.Time) {
  98. c.ValidUntil = t
  99. }
  100. // HasPassword queries if the Credentials has a password defined.
  101. func (c *Credentials) HasPassword() bool {
  102. if c.Password != "" {
  103. return true
  104. }
  105. return false
  106. }
  107. // SetADCredentials adds ADCredentials attributes to the credentials
  108. func (c *Credentials) SetADCredentials(a ADCredentials) {
  109. c.SetAttribute(AttributeKeyADCredentials, a)
  110. if a.FullName != "" {
  111. c.SetDisplayName(a.FullName)
  112. }
  113. if a.EffectiveName != "" {
  114. c.SetUserName(a.EffectiveName)
  115. }
  116. for i := range a.GroupMembershipSIDs {
  117. c.AddAuthzAttribute(a.GroupMembershipSIDs[i])
  118. }
  119. }
  120. // Methods to implement goidentity.Identity interface
  121. // UserName returns the credential's username.
  122. func (c *Credentials) UserName() string {
  123. return c.Username
  124. }
  125. // SetUserName sets the username value on the credential.
  126. func (c *Credentials) SetUserName(s string) {
  127. c.Username = s
  128. }
  129. // Domain returns the credential's domain.
  130. func (c *Credentials) Domain() string {
  131. return c.Realm
  132. }
  133. // SetDomain sets the domain value on the credential.
  134. func (c *Credentials) SetDomain(s string) {
  135. c.Realm = s
  136. }
  137. // DisplayName returns the credential's display name.
  138. func (c *Credentials) DisplayName() string {
  139. return c.displayName
  140. }
  141. // SetDisplayName sets the display name value on the credential.
  142. func (c *Credentials) SetDisplayName(s string) {
  143. c.displayName = s
  144. }
  145. // Human returns if the credential represents a human or not.
  146. func (c *Credentials) Human() bool {
  147. return c.human
  148. }
  149. // SetHuman sets the credential as human.
  150. func (c *Credentials) SetHuman(b bool) {
  151. c.human = b
  152. }
  153. // AuthTime returns the time the credential was authenticated.
  154. func (c *Credentials) AuthTime() time.Time {
  155. return c.authTime
  156. }
  157. // SetAuthTime sets the time the credential was authenticated.
  158. func (c *Credentials) SetAuthTime(t time.Time) {
  159. c.authTime = t
  160. }
  161. // AuthzAttributes returns the credentials authorizing attributes.
  162. func (c *Credentials) AuthzAttributes() []string {
  163. s := make([]string, len(c.groupMembership))
  164. i := 0
  165. for a := range c.groupMembership {
  166. s[i] = a
  167. i++
  168. }
  169. return s
  170. }
  171. // Authenticated indicates if the credential has been successfully authenticated or not.
  172. func (c *Credentials) Authenticated() bool {
  173. return c.authenticated
  174. }
  175. // SetAuthenticated sets the credential as having been successfully authenticated.
  176. func (c *Credentials) SetAuthenticated(b bool) {
  177. c.authenticated = b
  178. }
  179. // AddAuthzAttribute adds an authorization attribute to the credential.
  180. func (c *Credentials) AddAuthzAttribute(a string) {
  181. c.groupMembership[a] = true
  182. }
  183. // RemoveAuthzAttribute removes an authorization attribute from the credential.
  184. func (c *Credentials) RemoveAuthzAttribute(a string) {
  185. if _, ok := c.groupMembership[a]; !ok {
  186. return
  187. }
  188. delete(c.groupMembership, a)
  189. }
  190. // EnableAuthzAttribute toggles an authorization attribute to an enabled state on the credential.
  191. func (c *Credentials) EnableAuthzAttribute(a string) {
  192. if enabled, ok := c.groupMembership[a]; ok && !enabled {
  193. c.groupMembership[a] = true
  194. }
  195. }
  196. // DisableAuthzAttribute toggles an authorization attribute to a disabled state on the credential.
  197. func (c *Credentials) DisableAuthzAttribute(a string) {
  198. if enabled, ok := c.groupMembership[a]; ok && enabled {
  199. c.groupMembership[a] = false
  200. }
  201. }
  202. // Authorized indicates if the credential has the specified authorizing attribute.
  203. func (c *Credentials) Authorized(a string) bool {
  204. if enabled, ok := c.groupMembership[a]; ok && enabled {
  205. return true
  206. }
  207. return false
  208. }
  209. // SessionID returns the credential's session ID.
  210. func (c *Credentials) SessionID() string {
  211. return c.sessionID
  212. }
  213. // Expired indicates if the credential has expired.
  214. func (c *Credentials) Expired() bool {
  215. if !c.ValidUntil.IsZero() && time.Now().UTC().After(c.ValidUntil) {
  216. return true
  217. }
  218. return false
  219. }
  220. // Attributes returns the Credentials' attributes map.
  221. func (c *Credentials) Attributes() map[string]interface{} {
  222. return c.attributes
  223. }
  224. // SetAttribute sets the value of an attribute.
  225. func (c *Credentials) SetAttribute(k string, v interface{}) {
  226. c.attributes[k] = v
  227. }
  228. // SetAttributes replaces the attributes map with the one provided.
  229. func (c *Credentials) SetAttributes(a map[string]interface{}) {
  230. c.attributes = a
  231. }
  232. // RemoveAttribute deletes an attribute from the attribute map that has the key provided.
  233. func (c *Credentials) RemoveAttribute(k string) {
  234. delete(c.attributes, k)
  235. }