credentials.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // Package credentials provides credentials management for Kerberos 5 authentication.
  2. package credentials
  3. import (
  4. "github.com/hashicorp/go-uuid"
  5. "gopkg.in/jcmturner/gokrb5.v2/iana/nametype"
  6. "gopkg.in/jcmturner/gokrb5.v2/keytab"
  7. "gopkg.in/jcmturner/gokrb5.v2/types"
  8. "strings"
  9. "time"
  10. )
  11. const (
  12. // AttributeKeyADCredentials assigned number for AD credentials.
  13. AttributeKeyADCredentials = 1
  14. )
  15. // Credentials struct for a user.
  16. // Contains either a keytab, password or both.
  17. // Keytabs are used over passwords if both are defined.
  18. type Credentials struct {
  19. Username string
  20. displayName string
  21. Realm string
  22. CName types.PrincipalName
  23. Keytab keytab.Keytab
  24. Password string
  25. Attributes map[int]interface{}
  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.PrincipalName{
  57. NameType: nametype.KRB_NT_PRINCIPAL,
  58. NameString: strings.Split(username, "/"),
  59. },
  60. Keytab: keytab.NewKeytab(),
  61. Attributes: make(map[int]interface{}),
  62. sessionID: uid,
  63. }
  64. }
  65. // NewCredentialsFromPrincipal creates a new Credentials instance with the user details provides as a PrincipalName type.
  66. func NewCredentialsFromPrincipal(cname types.PrincipalName, realm string) Credentials {
  67. uid, err := uuid.GenerateUUID()
  68. if err != nil {
  69. uid = "00unique-sess-ions-uuid-unavailable0"
  70. }
  71. return Credentials{
  72. Username: cname.GetPrincipalNameString(),
  73. displayName: cname.GetPrincipalNameString(),
  74. Realm: realm,
  75. CName: cname,
  76. Keytab: keytab.NewKeytab(),
  77. Attributes: make(map[int]interface{}),
  78. groupMembership: make(map[string]bool),
  79. sessionID: uid,
  80. }
  81. }
  82. // WithKeytab sets the Keytab in the Credentials struct.
  83. func (c *Credentials) WithKeytab(kt keytab.Keytab) *Credentials {
  84. c.Keytab = kt
  85. return c
  86. }
  87. // WithPassword sets the password in the Credentials struct.
  88. func (c *Credentials) WithPassword(password string) *Credentials {
  89. c.Password = password
  90. return c
  91. }
  92. // HasKeytab queries if the Credentials has a keytab defined.
  93. func (c *Credentials) HasKeytab() bool {
  94. if len(c.Keytab.Entries) > 0 {
  95. return true
  96. }
  97. return false
  98. }
  99. // HasPassword queries if the Credentials has a password defined.
  100. func (c *Credentials) HasPassword() bool {
  101. if c.Password != "" {
  102. return true
  103. }
  104. return false
  105. }
  106. // SetADCredentials adds ADCredentials attributes to the credentials
  107. func (c *Credentials) SetADCredentials(a ADCredentials) {
  108. c.Attributes[AttributeKeyADCredentials] = a
  109. if a.FullName != "" {
  110. c.SetDisplayName(a.FullName)
  111. }
  112. if a.EffectiveName != "" {
  113. c.SetUserName(a.EffectiveName)
  114. }
  115. if a.LogonDomainName != "" {
  116. c.SetDomain(a.LogonDomainName)
  117. }
  118. for i := range a.GroupMembershipSIDs {
  119. c.AddAuthzAttribute(a.GroupMembershipSIDs[i])
  120. }
  121. }
  122. // Methods to implement goidentity.Identity interface
  123. // UserName returns the credential's username.
  124. func (c *Credentials) UserName() string {
  125. return c.Username
  126. }
  127. // SetUserName sets the username value on the credential.
  128. func (c *Credentials) SetUserName(s string) {
  129. c.Username = s
  130. }
  131. // Domain returns the credential's domain.
  132. func (c *Credentials) Domain() string {
  133. return c.Realm
  134. }
  135. // SetDomain sets the domain value on the credential.
  136. func (c *Credentials) SetDomain(s string) {
  137. c.Realm = s
  138. }
  139. // DisplayName returns the credential's display name.
  140. func (c *Credentials) DisplayName() string {
  141. return c.displayName
  142. }
  143. // SetDisplayName sets the display name value on the credential.
  144. func (c *Credentials) SetDisplayName(s string) {
  145. c.displayName = s
  146. }
  147. // Human returns if the credential represents a human or not.
  148. func (c *Credentials) Human() bool {
  149. return c.human
  150. }
  151. // SetHuman sets the credential as human.
  152. func (c *Credentials) SetHuman(b bool) {
  153. c.human = b
  154. }
  155. // AuthTime returns the time the credential was authenticated.
  156. func (c *Credentials) AuthTime() time.Time {
  157. return c.authTime
  158. }
  159. // SetAuthTime sets the time the credential was authenticated.
  160. func (c *Credentials) SetAuthTime(t time.Time) {
  161. c.authTime = t
  162. }
  163. // AuthzAttributes returns the credentials authorizing attributes.
  164. func (c *Credentials) AuthzAttributes() []string {
  165. s := make([]string, len(c.groupMembership))
  166. i := 0
  167. for a := range c.groupMembership {
  168. s[i] = a
  169. i++
  170. }
  171. return s
  172. }
  173. // Authenticated indicates if the credential has been successfully authenticated or not.
  174. func (c *Credentials) Authenticated() bool {
  175. return c.authenticated
  176. }
  177. // SetAuthenticated sets the credential as having been successfully authenticated.
  178. func (c *Credentials) SetAuthenticated(b bool) {
  179. c.authenticated = b
  180. }
  181. // AddAuthzAttribute adds an authorization attribute to the credential.
  182. func (c *Credentials) AddAuthzAttribute(a string) {
  183. c.groupMembership[a] = true
  184. }
  185. // RemoveAuthzAttribute removes an authorization attribute from the credential.
  186. func (c *Credentials) RemoveAuthzAttribute(a string) {
  187. if _, ok := c.groupMembership[a]; !ok {
  188. return
  189. }
  190. delete(c.groupMembership, a)
  191. }
  192. // EnableAuthzAttribute toggles an authorization attribute to an enabled state on the credential.
  193. func (c *Credentials) EnableAuthzAttribute(a string) {
  194. if enabled, ok := c.groupMembership[a]; ok && !enabled {
  195. c.groupMembership[a] = true
  196. }
  197. }
  198. // DisableAuthzAttribute toggles an authorization attribute to a disabled state on the credential.
  199. func (c *Credentials) DisableAuthzAttribute(a string) {
  200. if enabled, ok := c.groupMembership[a]; ok && enabled {
  201. c.groupMembership[a] = false
  202. }
  203. }
  204. // Authorized indicates if the credential has the specified authorizing attribute.
  205. func (c *Credentials) Authorized(a string) bool {
  206. if enabled, ok := c.groupMembership[a]; ok && enabled {
  207. return true
  208. }
  209. return false
  210. }
  211. // SessionID returns the credential's session ID.
  212. func (c *Credentials) SessionID() string {
  213. return c.sessionID
  214. }