control.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. "strconv"
  8. "gopkg.in/asn1-ber.v1"
  9. )
  10. const (
  11. ControlTypePaging = "1.2.840.113556.1.4.319"
  12. ControlTypeBeheraPasswordPolicy = "1.3.6.1.4.1.42.2.27.8.5.1"
  13. ControlTypeVChuPasswordMustChange = "2.16.840.1.113730.3.4.4"
  14. ControlTypeVChuPasswordWarning = "2.16.840.1.113730.3.4.5"
  15. ControlTypeManageDsaIT = "2.16.840.1.113730.3.4.2"
  16. )
  17. var ControlTypeMap = map[string]string{
  18. ControlTypePaging: "Paging",
  19. ControlTypeBeheraPasswordPolicy: "Password Policy - Behera Draft",
  20. ControlTypeManageDsaIT: "Manage DSA IT",
  21. }
  22. type Control interface {
  23. GetControlType() string
  24. Encode() *ber.Packet
  25. String() string
  26. }
  27. type ControlString struct {
  28. ControlType string
  29. Criticality bool
  30. ControlValue string
  31. }
  32. func (c *ControlString) GetControlType() string {
  33. return c.ControlType
  34. }
  35. func (c *ControlString) Encode() *ber.Packet {
  36. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
  37. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, c.ControlType, "Control Type ("+ControlTypeMap[c.ControlType]+")"))
  38. if c.Criticality {
  39. packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality"))
  40. }
  41. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, string(c.ControlValue), "Control Value"))
  42. return packet
  43. }
  44. func (c *ControlString) String() string {
  45. return fmt.Sprintf("Control Type: %s (%q) Criticality: %t Control Value: %s", ControlTypeMap[c.ControlType], c.ControlType, c.Criticality, c.ControlValue)
  46. }
  47. type ControlPaging struct {
  48. PagingSize uint32
  49. Cookie []byte
  50. }
  51. func (c *ControlPaging) GetControlType() string {
  52. return ControlTypePaging
  53. }
  54. func (c *ControlPaging) Encode() *ber.Packet {
  55. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
  56. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypePaging, "Control Type ("+ControlTypeMap[ControlTypePaging]+")"))
  57. p2 := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Control Value (Paging)")
  58. seq := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value")
  59. seq.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, uint64(c.PagingSize), "Paging Size"))
  60. cookie := ber.Encode(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, nil, "Cookie")
  61. cookie.Value = c.Cookie
  62. cookie.Data.Write(c.Cookie)
  63. seq.AppendChild(cookie)
  64. p2.AppendChild(seq)
  65. packet.AppendChild(p2)
  66. return packet
  67. }
  68. func (c *ControlPaging) String() string {
  69. return fmt.Sprintf(
  70. "Control Type: %s (%q) Criticality: %t PagingSize: %d Cookie: %q",
  71. ControlTypeMap[ControlTypePaging],
  72. ControlTypePaging,
  73. false,
  74. c.PagingSize,
  75. c.Cookie)
  76. }
  77. func (c *ControlPaging) SetCookie(cookie []byte) {
  78. c.Cookie = cookie
  79. }
  80. type ControlBeheraPasswordPolicy struct {
  81. Expire int64
  82. Grace int64
  83. Error int8
  84. ErrorString string
  85. }
  86. func (c *ControlBeheraPasswordPolicy) GetControlType() string {
  87. return ControlTypeBeheraPasswordPolicy
  88. }
  89. func (c *ControlBeheraPasswordPolicy) Encode() *ber.Packet {
  90. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
  91. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeBeheraPasswordPolicy, "Control Type ("+ControlTypeMap[ControlTypeBeheraPasswordPolicy]+")"))
  92. return packet
  93. }
  94. func (c *ControlBeheraPasswordPolicy) String() string {
  95. return fmt.Sprintf(
  96. "Control Type: %s (%q) Criticality: %t Expire: %d Grace: %d Error: %d, ErrorString: %s",
  97. ControlTypeMap[ControlTypeBeheraPasswordPolicy],
  98. ControlTypeBeheraPasswordPolicy,
  99. false,
  100. c.Expire,
  101. c.Grace,
  102. c.Error,
  103. c.ErrorString)
  104. }
  105. type ControlVChuPasswordMustChange struct {
  106. MustChange bool
  107. }
  108. func (c *ControlVChuPasswordMustChange) GetControlType() string {
  109. return ControlTypeVChuPasswordMustChange
  110. }
  111. func (c *ControlVChuPasswordMustChange) Encode() *ber.Packet {
  112. return nil
  113. }
  114. func (c *ControlVChuPasswordMustChange) String() string {
  115. return fmt.Sprintf(
  116. "Control Type: %s (%q) Criticality: %t MustChange: %b",
  117. ControlTypeMap[ControlTypeVChuPasswordMustChange],
  118. ControlTypeVChuPasswordMustChange,
  119. false,
  120. c.MustChange)
  121. }
  122. type ControlVChuPasswordWarning struct {
  123. Expire int64
  124. }
  125. func (c *ControlVChuPasswordWarning) GetControlType() string {
  126. return ControlTypeVChuPasswordWarning
  127. }
  128. func (c *ControlVChuPasswordWarning) Encode() *ber.Packet {
  129. return nil
  130. }
  131. func (c *ControlVChuPasswordWarning) String() string {
  132. return fmt.Sprintf(
  133. "Control Type: %s (%q) Criticality: %t Expire: %b",
  134. ControlTypeMap[ControlTypeVChuPasswordWarning],
  135. ControlTypeVChuPasswordWarning,
  136. false,
  137. c.Expire)
  138. }
  139. type ControlManageDsaIT struct {
  140. Criticality bool
  141. }
  142. func (c *ControlManageDsaIT) GetControlType() string {
  143. return ControlTypeManageDsaIT
  144. }
  145. func (c *ControlManageDsaIT) Encode() *ber.Packet {
  146. //FIXME
  147. packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control")
  148. packet.AppendChild(ber.NewString(ber.ClassUniversal, ber.TypePrimitive, ber.TagOctetString, ControlTypeManageDsaIT, "Control Type ("+ControlTypeMap[ControlTypeManageDsaIT]+")"))
  149. if c.Criticality {
  150. packet.AppendChild(ber.NewBoolean(ber.ClassUniversal, ber.TypePrimitive, ber.TagBoolean, c.Criticality, "Criticality"))
  151. }
  152. return packet
  153. }
  154. func (c *ControlManageDsaIT) String() string {
  155. return fmt.Sprintf(
  156. "Control Type: %s (%q) Criticality: %t",
  157. ControlTypeMap[ControlTypeManageDsaIT],
  158. ControlTypeManageDsaIT,
  159. c.Criticality)
  160. }
  161. func NewControlManageDsaIT(Criticality bool) *ControlManageDsaIT {
  162. return &ControlManageDsaIT{Criticality: Criticality}
  163. }
  164. func FindControl(controls []Control, controlType string) Control {
  165. for _, c := range controls {
  166. if c.GetControlType() == controlType {
  167. return c
  168. }
  169. }
  170. return nil
  171. }
  172. func DecodeControl(packet *ber.Packet) Control {
  173. ControlType := packet.Children[0].Value.(string)
  174. Criticality := false
  175. packet.Children[0].Description = "Control Type (" + ControlTypeMap[ControlType] + ")"
  176. value := packet.Children[1]
  177. if len(packet.Children) == 3 {
  178. value = packet.Children[2]
  179. packet.Children[1].Description = "Criticality"
  180. Criticality = packet.Children[1].Value.(bool)
  181. }
  182. value.Description = "Control Value"
  183. switch ControlType {
  184. case ControlTypePaging:
  185. value.Description += " (Paging)"
  186. c := new(ControlPaging)
  187. if value.Value != nil {
  188. valueChildren := ber.DecodePacket(value.Data.Bytes())
  189. value.Data.Truncate(0)
  190. value.Value = nil
  191. value.AppendChild(valueChildren)
  192. }
  193. value = value.Children[0]
  194. value.Description = "Search Control Value"
  195. value.Children[0].Description = "Paging Size"
  196. value.Children[1].Description = "Cookie"
  197. c.PagingSize = uint32(value.Children[0].Value.(int64))
  198. c.Cookie = value.Children[1].Data.Bytes()
  199. value.Children[1].Value = c.Cookie
  200. return c
  201. case ControlTypeBeheraPasswordPolicy:
  202. value.Description += " (Password Policy - Behera)"
  203. c := NewControlBeheraPasswordPolicy()
  204. if value.Value != nil {
  205. valueChildren := ber.DecodePacket(value.Data.Bytes())
  206. value.Data.Truncate(0)
  207. value.Value = nil
  208. value.AppendChild(valueChildren)
  209. }
  210. sequence := value.Children[0]
  211. for _, child := range sequence.Children {
  212. if child.Tag == 0 {
  213. //Warning
  214. child := child.Children[0]
  215. packet := ber.DecodePacket(child.Data.Bytes())
  216. val, ok := packet.Value.(int64)
  217. if ok {
  218. if child.Tag == 0 {
  219. //timeBeforeExpiration
  220. c.Expire = val
  221. child.Value = c.Expire
  222. } else if child.Tag == 1 {
  223. //graceAuthNsRemaining
  224. c.Grace = val
  225. child.Value = c.Grace
  226. }
  227. }
  228. } else if child.Tag == 1 {
  229. // Error
  230. packet := ber.DecodePacket(child.Data.Bytes())
  231. val, ok := packet.Value.(int8)
  232. if !ok {
  233. // what to do?
  234. val = -1
  235. }
  236. c.Error = val
  237. child.Value = c.Error
  238. c.ErrorString = BeheraPasswordPolicyErrorMap[c.Error]
  239. }
  240. }
  241. return c
  242. case ControlTypeVChuPasswordMustChange:
  243. c := &ControlVChuPasswordMustChange{MustChange: true}
  244. return c
  245. case ControlTypeVChuPasswordWarning:
  246. c := &ControlVChuPasswordWarning{Expire: -1}
  247. expireStr := ber.DecodeString(value.Data.Bytes())
  248. expire, err := strconv.ParseInt(expireStr, 10, 64)
  249. if err != nil {
  250. return nil
  251. }
  252. c.Expire = expire
  253. value.Value = c.Expire
  254. return c
  255. }
  256. c := new(ControlString)
  257. c.ControlType = ControlType
  258. c.Criticality = Criticality
  259. c.ControlValue = value.Value.(string)
  260. return c
  261. }
  262. func NewControlString(controlType string, criticality bool, controlValue string) *ControlString {
  263. return &ControlString{
  264. ControlType: controlType,
  265. Criticality: criticality,
  266. ControlValue: controlValue,
  267. }
  268. }
  269. func NewControlPaging(pagingSize uint32) *ControlPaging {
  270. return &ControlPaging{PagingSize: pagingSize}
  271. }
  272. func NewControlBeheraPasswordPolicy() *ControlBeheraPasswordPolicy {
  273. return &ControlBeheraPasswordPolicy{
  274. Expire: -1,
  275. Grace: -1,
  276. Error: -1,
  277. }
  278. }
  279. func encodeControls(controls []Control) *ber.Packet {
  280. packet := ber.Encode(ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls")
  281. for _, control := range controls {
  282. packet.AppendChild(control.Encode())
  283. }
  284. return packet
  285. }