func DebugBinaryFile(fileName string) error { file, err := ioutil.ReadFile(fileName) if err != nil { return NewError(ErrorDebugging, err) } ber.PrintBytes(os.Stdout, file, "") packet := ber.DecodePacket(file) addLDAPDescriptions(packet) ber.PrintPacket(packet) return nil }
// ParseDN returns a distinguishedName or an error func ParseDN(str string) (*DN, error) { dn := new(DN) dn.RDNs = make([]*RelativeDN, 0) rdn := new(RelativeDN) rdn.Attributes = make([]*AttributeTypeAndValue, 0) buffer := bytes.Buffer{} attribute := new(AttributeTypeAndValue) escaping := false for i := 0; i < len(str); i++ { char := str[i] if escaping { escaping = false switch char { case ' ', '"', '#', '+', ',', ';', '<', '=', '>', '\\': buffer.WriteByte(char) continue } // Not a special character, assume hex encoded octet if len(str) == i+1 { return nil, errors.New("Got corrupted escaped character") } dst := []byte{0} n, err := enchex.Decode([]byte(dst), []byte(str[i:i+2])) if err != nil { return nil, fmt.Errorf("Failed to decode escaped character: %s", err) } else if n != 1 { return nil, fmt.Errorf("Expected 1 byte when un-escaping, got %d", n) } buffer.WriteByte(dst[0]) i++ } else if char == '\\' { escaping = true } else if char == '=' { attribute.Type = buffer.String() buffer.Reset() // Special case: If the first character in the value is # the // following data is BER encoded so we can just fast forward // and decode. if len(str) > i+1 && str[i+1] == '#' { i += 2 index := strings.IndexAny(str[i:], ",+") data := str if index > 0 { data = str[i : i+index] } else { data = str[i:] } rawBER, err := enchex.DecodeString(data) if err != nil { return nil, fmt.Errorf("Failed to decode BER encoding: %s", err) } packet := ber.DecodePacket(rawBER) buffer.WriteString(packet.Data.String()) i += len(data) - 1 } } else if char == ',' || char == '+' { // We're done with this RDN or value, push it attribute.Value = buffer.String() rdn.Attributes = append(rdn.Attributes, attribute) attribute = new(AttributeTypeAndValue) if char == ',' { dn.RDNs = append(dn.RDNs, rdn) rdn = new(RelativeDN) rdn.Attributes = make([]*AttributeTypeAndValue, 0) } buffer.Reset() } else { buffer.WriteByte(char) } } if buffer.Len() > 0 { if len(attribute.Type) == 0 { return nil, errors.New("DN ended with incomplete type, value pair") } attribute.Value = buffer.String() rdn.Attributes = append(rdn.Attributes, attribute) dn.RDNs = append(dn.RDNs, rdn) } return dn, nil }
func addControlDescriptions(packet *ber.Packet) { packet.Description = "Controls" for _, child := range packet.Children { child.Description = "Control" child.Children[0].Description = "Control Type (" + ControlTypeMap[child.Children[0].Value.(string)] + ")" value := child.Children[1] if len(child.Children) == 3 { child.Children[1].Description = "Criticality" value = child.Children[2] } value.Description = "Control Value" switch child.Children[0].Value.(string) { case ControlTypePaging: value.Description += " (Paging)" if value.Value != nil { valueChildren := ber.DecodePacket(value.Data.Bytes()) value.Data.Truncate(0) value.Value = nil valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes() value.AppendChild(valueChildren) } value.Children[0].Description = "Real Search Control Value" value.Children[0].Children[0].Description = "Paging Size" value.Children[0].Children[1].Description = "Cookie" case ControlTypeBeheraPasswordPolicy: value.Description += " (Password Policy - Behera Draft)" if value.Value != nil { valueChildren := ber.DecodePacket(value.Data.Bytes()) value.Data.Truncate(0) value.Value = nil value.AppendChild(valueChildren) } sequence := value.Children[0] for _, child := range sequence.Children { if child.Tag == 0 { //Warning child := child.Children[0] packet := ber.DecodePacket(child.Data.Bytes()) val, ok := packet.Value.(int64) if ok { if child.Tag == 0 { //timeBeforeExpiration value.Description += " (TimeBeforeExpiration)" child.Value = val } else if child.Tag == 1 { //graceAuthNsRemaining value.Description += " (GraceAuthNsRemaining)" child.Value = val } } } else if child.Tag == 1 { // Error packet := ber.DecodePacket(child.Data.Bytes()) val, ok := packet.Value.(int8) if !ok { val = -1 } child.Description = "Error" child.Value = val } } } } }
func addControlDescriptions(packet *ber.Packet) { packet.Description = "Controls" for _, child := range packet.Children { var value *ber.Packet controlType := "" child.Description = "Control" switch len(child.Children) { case 0: // at least one child is required for control type continue case 1: // just type, no criticality or value controlType = child.Children[0].Value.(string) child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")" case 2: controlType = child.Children[0].Value.(string) child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")" // Children[1] could be criticality or value (both are optional) // duck-type on whether this is a boolean if _, ok := child.Children[1].Value.(bool); ok { child.Children[1].Description = "Criticality" } else { child.Children[1].Description = "Control Value" value = child.Children[1] } case 3: // criticality and value present controlType = child.Children[0].Value.(string) child.Children[0].Description = "Control Type (" + ControlTypeMap[controlType] + ")" child.Children[1].Description = "Criticality" child.Children[2].Description = "Control Value" value = child.Children[2] default: // more than 3 children is invalid continue } if value == nil { continue } switch controlType { case ControlTypePaging: value.Description += " (Paging)" if value.Value != nil { valueChildren := ber.DecodePacket(value.Data.Bytes()) value.Data.Truncate(0) value.Value = nil valueChildren.Children[1].Value = valueChildren.Children[1].Data.Bytes() value.AppendChild(valueChildren) } value.Children[0].Description = "Real Search Control Value" value.Children[0].Children[0].Description = "Paging Size" value.Children[0].Children[1].Description = "Cookie" case ControlTypeBeheraPasswordPolicy: value.Description += " (Password Policy - Behera Draft)" if value.Value != nil { valueChildren := ber.DecodePacket(value.Data.Bytes()) value.Data.Truncate(0) value.Value = nil value.AppendChild(valueChildren) } sequence := value.Children[0] for _, child := range sequence.Children { if child.Tag == 0 { //Warning warningPacket := child.Children[0] packet := ber.DecodePacket(warningPacket.Data.Bytes()) val, ok := packet.Value.(int64) if ok { if warningPacket.Tag == 0 { //timeBeforeExpiration value.Description += " (TimeBeforeExpiration)" warningPacket.Value = val } else if warningPacket.Tag == 1 { //graceAuthNsRemaining value.Description += " (GraceAuthNsRemaining)" warningPacket.Value = val } } } else if child.Tag == 1 { // Error packet := ber.DecodePacket(child.Data.Bytes()) val, ok := packet.Value.(int8) if !ok { val = -1 } child.Description = "Error" child.Value = val } } } } }