credentials.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Package credentials provides credentials management for Kerberos 5 authentication.
  2. package credentials
  3. import (
  4. "github.com/hashicorp/go-uuid"
  5. "github.com/jcmturner/gokrb5/iana/nametype"
  6. "github.com/jcmturner/gokrb5/keytab"
  7. "github.com/jcmturner/gokrb5/types"
  8. "time"
  9. )
  10. const (
  11. // AttributeKeyADCredentials assigned number for AD credentials.
  12. AttributeKeyADCredentials = 1
  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. Realm string
  20. CName types.PrincipalName
  21. Keytab keytab.Keytab
  22. Password string
  23. Attributes map[int]interface{}
  24. authenticated bool
  25. human bool
  26. authTime time.Time
  27. groupMembership map[string]bool
  28. sessionID string
  29. }
  30. // ADCredentials contains information obtained from the PAC.
  31. type ADCredentials struct {
  32. EffectiveName string
  33. FullName string
  34. UserID int
  35. PrimaryGroupID int
  36. LogOnTime time.Time
  37. LogOffTime time.Time
  38. PasswordLastSet time.Time
  39. GroupMembershipSIDs []string
  40. LogonDomainName string
  41. LogonDomainID string
  42. LogonServer string
  43. }
  44. // NewCredentials creates a new Credentials instance.
  45. func NewCredentials(username string, realm string) Credentials {
  46. uid, err := uuid.GenerateUUID()
  47. if err != nil {
  48. uid = "00unique-sess-ions-uuid-unavailable0"
  49. }
  50. return Credentials{
  51. Username: username,
  52. Realm: realm,
  53. CName: types.PrincipalName{
  54. NameType: nametype.KRB_NT_PRINCIPAL,
  55. NameString: []string{username},
  56. },
  57. Keytab: keytab.NewKeytab(),
  58. Attributes: make(map[int]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. Realm: realm,
  71. CName: cname,
  72. Keytab: keytab.NewKeytab(),
  73. Attributes: make(map[int]interface{}),
  74. sessionID: uid,
  75. }
  76. }
  77. // WithKeytab sets the Keytab in the Credentials struct.
  78. func (c *Credentials) WithKeytab(kt keytab.Keytab) *Credentials {
  79. c.Keytab = kt
  80. return c
  81. }
  82. // WithPassword sets the password in the Credentials struct.
  83. func (c *Credentials) WithPassword(password string) *Credentials {
  84. c.Password = password
  85. return c
  86. }
  87. // HasKeytab queries if the Credentials has a keytab defined.
  88. func (c *Credentials) HasKeytab() bool {
  89. if len(c.Keytab.Entries) > 0 {
  90. return true
  91. }
  92. return false
  93. }
  94. // HasPassword queries if the Credentials has a password defined.
  95. func (c *Credentials) HasPassword() bool {
  96. if c.Password != "" {
  97. return true
  98. }
  99. return false
  100. }
  101. // SetADCredentials adds ADCredentials attributes to the credentials
  102. func (c *Credentials) SetADCredentials(a ADCredentials) {
  103. c.Attributes[AttributeKeyADCredentials] = a
  104. if a.FullName != "" {
  105. c.SetDisplayName(a.FullName)
  106. }
  107. for i := range a.GroupMembershipSIDs {
  108. c.AddAuthzAttribute(a.GroupMembershipSIDs[i])
  109. }
  110. }
  111. // Methods to implement goidentity.Identity interface
  112. // UserName returns the credential's username.
  113. func (c *Credentials) UserName() string {
  114. return c.Username
  115. }
  116. // SetUserName sets the username value on the credential.
  117. func (c *Credentials) SetUserName(s string) {
  118. c.Username = s
  119. }
  120. // Domain returns the credential's domain.
  121. func (c *Credentials) Domain() string {
  122. return c.Realm
  123. }
  124. // SetDomain sets the domain value on the credential.
  125. func (c *Credentials) SetDomain(s string) {
  126. c.Realm = s
  127. }
  128. // DisplayName returns the credential's display name.
  129. func (c *Credentials) DisplayName() string {
  130. return c.Username
  131. }
  132. // SetDisplayName sets the display name value on the credential.
  133. func (c *Credentials) SetDisplayName(s string) {
  134. c.Username = s
  135. }
  136. // Human returns if the credential represents a human or not.
  137. func (c *Credentials) Human() bool {
  138. return c.human
  139. }
  140. // SetHuman sets the credential as human.
  141. func (c *Credentials) SetHuman(b bool) {
  142. c.human = b
  143. }
  144. // AuthTime returns the time the credential was authenticated.
  145. func (c *Credentials) AuthTime() time.Time {
  146. return c.authTime
  147. }
  148. // SetAuthTime sets the time the credential was authenticated.
  149. func (c *Credentials) SetAuthTime(t time.Time) {
  150. c.authTime = t
  151. }
  152. // AuthzAttributes returns the credentials authorizing attributes.
  153. func (c *Credentials) AuthzAttributes() []string {
  154. s := make([]string, len(c.groupMembership))
  155. i := 0
  156. for a := range c.groupMembership {
  157. s[i] = a
  158. i++
  159. }
  160. return s
  161. }
  162. // Authenticated indicates if the credential has been successfully authenticated or not.
  163. func (c *Credentials) Authenticated() bool {
  164. return c.authenticated
  165. }
  166. // SetAuthenticated sets the credential as having been successfully authenticated.
  167. func (c *Credentials) SetAuthenticated(b bool) {
  168. c.authenticated = b
  169. }
  170. // AddAuthzAttribute adds an authorization attribute to the credential.
  171. func (c *Credentials) AddAuthzAttribute(a string) {
  172. c.groupMembership[a] = true
  173. }
  174. // RemoveAuthzAttribute removes an authorization attribute from the credential.
  175. func (c *Credentials) RemoveAuthzAttribute(a string) {
  176. if _, ok := c.groupMembership[a]; !ok {
  177. return
  178. }
  179. delete(c.groupMembership, a)
  180. }
  181. // EnableAuthzAttribute toggles an authorization attribute to an enabled state on the credential.
  182. func (c *Credentials) EnableAuthzAttribute(a string) {
  183. if enabled, ok := c.groupMembership[a]; ok && !enabled {
  184. c.groupMembership[a] = true
  185. }
  186. }
  187. // DisableAuthzAttribute toggles an authorization attribute to a disabled state on the credential.
  188. func (c *Credentials) DisableAuthzAttribute(a string) {
  189. if enabled, ok := c.groupMembership[a]; ok && enabled {
  190. c.groupMembership[a] = false
  191. }
  192. }
  193. // Authorized indicates if the credential has the specified authorizing attribute.
  194. func (c *Credentials) Authorized(a string) bool {
  195. if enabled, ok := c.groupMembership[a]; ok && enabled {
  196. return true
  197. }
  198. return false
  199. }
  200. // SessionID returns the credential's session ID.
  201. func (c *Credentials) SessionID() string {
  202. return c.sessionID
  203. }