diff options
Diffstat (limited to 'control.go')
-rw-r--r-- | control.go | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/control.go b/control.go new file mode 100644 index 0000000..af145b2 --- /dev/null +++ b/control.go @@ -0,0 +1,157 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This package provides LDAP client functions. +package ldap + +import ( + "github.com/mmitton/asn1-ber" + "fmt" +) + +const ( + ControlTypePaging = "1.2.840.113556.1.4.319" +) + +var ControlTypeMap = map[ string ] string { + ControlTypePaging : "Paging", +} + +type Control interface { + GetControlType() string + Encode() *ber.Packet + String() string +} + +type ControlString struct { + ControlType string + Criticality bool + ControlValue string +} + +func (c *ControlString) GetControlType() string { + return c.ControlType +} + +func (c *ControlString) Encode() (p *ber.Packet) { + p = ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control" ) + p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, c.ControlType, "Control Type (" + ControlTypeMap[ c.ControlType ] + ")" ) ) + if c.Criticality { + p.AppendChild( ber.NewBoolean( ber.ClassUniversal, ber.TypePrimative, ber.TagBoolean, c.Criticality, "Criticality" ) ) + } + p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, c.ControlValue, "Control Value" ) ) + return +} + +func (c *ControlString) String() string { + return fmt.Sprintf( "Control Type: %s (%q) Criticality: %s Control Value: %s", ControlTypeMap[ c.ControlType ], c.ControlType, c.Criticality, c.ControlValue ) +} + +type ControlPaging struct { + PagingSize uint32 + Cookie []byte +} + +func (c *ControlPaging) GetControlType() string { + return ControlTypePaging +} + +func (c *ControlPaging) Encode() (p *ber.Packet) { + p = ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Control" ) + p.AppendChild( ber.NewString( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, ControlTypePaging, "Control Type (" + ControlTypeMap[ ControlTypePaging ] + ")" ) ) + + p2 := ber.Encode( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, nil, "Control Value (Paging)" ) + seq := ber.Encode( ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "Search Control Value" ) + seq.AppendChild( ber.NewInteger( ber.ClassUniversal, ber.TypePrimative, ber.TagInteger, uint64(c.PagingSize), "Paging Size" ) ) + cookie := ber.Encode( ber.ClassUniversal, ber.TypePrimative, ber.TagOctetString, nil, "Cookie" ) + cookie.Value = c.Cookie + cookie.Data.Write( c.Cookie ) + seq.AppendChild( cookie ) + p2.AppendChild( seq ) + + p.AppendChild( p2 ) + return +} + +func (c *ControlPaging) String() string { + return fmt.Sprintf( + "Control Type: %s (%q) Criticality: %s PagingSize: %d Cookie: %q", + ControlTypeMap[ ControlTypePaging ], + ControlTypePaging, + false, + c.PagingSize, + c.Cookie ) +} + +func (c *ControlPaging) SetCookie( Cookie []byte ) { + c.Cookie = Cookie +} + +func FindControl( Controls []Control, ControlType string ) Control { + for _, c := range Controls { + if c.GetControlType() == ControlType { + return c + } + } + return nil +} + +func DecodeControl( p *ber.Packet ) Control { + ControlType := p.Children[ 0 ].Value.(string) + Criticality := false + + p.Children[ 0 ].Description = "Control Type (" + ControlTypeMap[ ControlType ] + ")" + value := p.Children[ 1 ] + if len( p.Children ) == 3 { + value = p.Children[ 2 ] + p.Children[ 1 ].Description = "Criticality" + Criticality = p.Children[ 1 ].Value.(bool) + } + + value.Description = "Control Value" + switch ControlType { + case ControlTypePaging: + value.Description += " (Paging)" + c := new( ControlPaging ) + if value.Value != nil { + value_children := ber.DecodePacket( value.Data.Bytes() ) + value.Data.Truncate( 0 ) + value.Value = nil + value.AppendChild( value_children ) + } + value = value.Children[ 0 ] + value.Description = "Search Control Value" + value.Children[ 0 ].Description = "Paging Size" + value.Children[ 1 ].Description = "Cookie" + c.PagingSize = uint32( value.Children[ 0 ].Value.(uint64) ) + c.Cookie = value.Children[ 1 ].Data.Bytes() + value.Children[ 1 ].Value = c.Cookie + return c + } + c := new( ControlString ) + c.ControlType = ControlType + c.Criticality = Criticality + c.ControlValue = value.Value.(string) + return c +} + +func NewControlString( ControlType string, Criticality bool, ControlValue string ) *ControlString { + return &ControlString{ + ControlType: ControlType, + Criticality: Criticality, + ControlValue: ControlValue, + } +} + +func NewControlPaging( PagingSize uint32 ) *ControlPaging { + return &ControlPaging{ PagingSize: PagingSize } +} + +func encodeControls( Controls []Control ) *ber.Packet { + p := ber.Encode( ber.ClassContext, ber.TypeConstructed, 0, nil, "Controls" ) + for _, control := range Controls { + p.AppendChild( control.Encode() ) + } + return p +} |