PrincipalName.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package types
  2. import (
  3. "strings"
  4. "gopkg.in/jcmturner/gokrb5.v7/iana/nametype"
  5. )
  6. // Reference: https://www.ietf.org/rfc/rfc4120.txt
  7. // Section: 5.2.2
  8. // PrincipalName implements RFC 4120 type: https://tools.ietf.org/html/rfc4120#section-5.2.2
  9. type PrincipalName struct {
  10. NameType int32 `asn1:"explicit,tag:0"`
  11. NameString []string `asn1:"generalstring,explicit,tag:1"`
  12. }
  13. // NewPrincipalName creates a new PrincipalName from the name type int32 and name string provided.
  14. func NewPrincipalName(ntype int32, spn string) PrincipalName {
  15. return PrincipalName{
  16. NameType: ntype,
  17. NameString: strings.Split(spn, "/"),
  18. }
  19. }
  20. // GetSalt returns a salt derived from the PrincipalName.
  21. func (pn PrincipalName) GetSalt(realm string) string {
  22. var sb []byte
  23. sb = append(sb, realm...)
  24. for _, n := range pn.NameString {
  25. sb = append(sb, n...)
  26. }
  27. return string(sb)
  28. }
  29. // Equal tests if the PrincipalName is equal to the one provided.
  30. func (pn PrincipalName) Equal(n PrincipalName) bool {
  31. //https://tools.ietf.org/html/rfc4120#section-6.2 - the name type is not significant when checking for equivalence
  32. for i, s := range pn.NameString {
  33. if n.NameString[i] != s {
  34. return false
  35. }
  36. }
  37. return true
  38. }
  39. // PrincipalNameString returns the PrincipalName in string form.
  40. func (pn PrincipalName) PrincipalNameString() string {
  41. return strings.Join(pn.NameString, "/")
  42. }
  43. // ParseSPNString will parse a string in the format <service>/<name>@<realm>
  44. // a PrincipalName type will be returned with the name type set to KRB_NT_PRINCIPAL(1)
  45. // and the realm will be returned as a string. If the "@<realm>" suffix
  46. // is not included in the SPN then the value of realm string returned will be ""
  47. func ParseSPNString(spn string) (pn PrincipalName, realm string) {
  48. if strings.Contains(spn, "@") {
  49. s := strings.Split(spn, "@")
  50. realm = s[len(s)-1]
  51. spn = strings.TrimSuffix(spn, "@"+realm)
  52. }
  53. pn = NewPrincipalName(nametype.KRB_NT_PRINCIPAL, spn)
  54. return
  55. }