You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.6 KiB

10 years ago
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ldap
  5. import (
  6. "fmt"
  7. "github.com/gogits/gogs/modules/asn1-ber"
  8. )
  9. const (
  10. ControlTypePaging = "1.2.840.113556.1.4.319"
  11. )
  12. var ControlTypeMap = map[string]string{
  13. ControlTypePaging: "Paging",
  14. }
  15. type Control interface {
  16. GetControlType() string
  17. Encode() *ber.Packet
  18. String() string
  19. }
  20. type ControlString struct {
  21. ControlType string
  22. Criticality bool
  23. ControlValue string
  24. }
  25. func (c *ControlString) GetControlType() string {
  26. return c.ControlType
  27. }
  28. func (c *ControlString) Encode() *ber.Packet {
  29. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
  30. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+ControlTypeMap[c.ControlType]+")"))
  31. if c.Criticality {
  32. packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality"))
  33. }
  34. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlValue, "Control Value"))
  35. return packet
  36. }
  37. func (c *ControlString) String() string {
  38. return fmt.Sprintf("Control Type: %s (%q) Criticality: %t Control Value: %s", ControlTypeMap[c.ControlType], c.ControlType, c.Criticality, c.ControlValue)
  39. }
  40. type ControlPaging struct {
  41. PagingSize uint32
  42. Cookie []byte
  43. }
  44. func (c *ControlPaging) GetControlType() string {
  45. return ControlTypePaging
  46. }
  47. func (c *ControlPaging) Encode() *ber.Packet {
  48. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
  49. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypePaging, "Control Type ("+ControlTypeMap[ControlTypePaging]+")"))
  50. p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)")
  51. seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value")
  52. seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(c.PagingSize), "Paging Size"))
  53. cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie")
  54. cookie.Value = c.Cookie
  55. cookie.Data.Write(c.Cookie)
  56. seq.AppendChild(cookie)
  57. p2.AppendChild(seq)
  58. packet.AppendChild(p2)
  59. return packet
  60. }
  61. func (c *ControlPaging) String() string {
  62. return fmt.Sprintf(
  63. "Control Type: %s (%q) Criticality: %t PagingSize: %d Cookie: %q",
  64. ControlTypeMap[ControlTypePaging],
  65. ControlTypePaging,
  66. false,
  67. c.PagingSize,
  68. c.Cookie)
  69. }
  70. func (c *ControlPaging) SetCookie(cookie []byte) {
  71. c.Cookie = cookie
  72. }
  73. func FindControl(controls []Control, controlType string) Control {
  74. for _, c := range controls {
  75. if c.GetControlType() == controlType {
  76. return c
  77. }
  78. }
  79. return nil
  80. }
  81. func DecodeControl(packet *ber.Packet) Control {
  82. ControlType := packet.Children[0].Value.(string)
  83. Criticality := false
  84. packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")"
  85. value := packet.Children[1]
  86. if len(packet.Children) == 3 {
  87. value = packet.Children[2]
  88. packet.Children[1].Description = "Criticality"
  89. Criticality = packet.Children[1].Value.(bool)
  90. }
  91. value.Description = "Control Value"
  92. switch ControlType {
  93. case ControlTypePaging:
  94. value.Description += " (Paging)"
  95. c := new(ControlPaging)
  96. if value.Value != nil {
  97. valueChildren := ber.DecodePacket(value.Data.Bytes())
  98. value.Data.Truncate(0)
  99. value.Value = nil
  100. value.AppendChild(valueChildren)
  101. }
  102. value = value.Children[0]
  103. value.Description = "Search Control Value"
  104. value.Children[0].Description = "Paging Size"
  105. value.Children[1].Description = "Cookie"
  106. c.PagingSize = uint32(value.Children[0].Value.(uint64))
  107. c.Cookie = value.Children[1].Data.Bytes()
  108. value.Children[1].Value = c.Cookie
  109. return c
  110. }
  111. c := new(ControlString)
  112. c.ControlType = ControlType
  113. c.Criticality = Criticality
  114. c.ControlValue = value.Value.(string)
  115. return c
  116. }
  117. func NewControlString(controlType string, criticality bool, controlValue string) *ControlString {
  118. return &ControlString{
  119. ControlType: controlType,
  120. Criticality: criticality,
  121. ControlValue: controlValue,
  122. }
  123. }
  124. func NewControlPaging(pagingSize uint32) *ControlPaging {
  125. return &ControlPaging{PagingSize: pagingSize}
  126. }
  127. func encodeControls(controls []Control) *ber.Packet {
  128. packet := ber.Encode(ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls")
  129. for _, control := range controls {
  130. packet.AppendChild(control.Encode())
  131. }
  132. return packet
  133. }