credentials.go 6.4 KB

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